Thank you for taking the time to read this and I will appreciate every single response no mater the quality of content. :)
I'm trying to create a php script which searches a text file for specific text. A person types in the specific text within a HTML form and the php script should search for that specific text within the text file.
The value of the input field of the HTML form is "username" and within the php document, the variable "$username" is the entered data, example shown below:
$username = $_POST['username'];
The text file below is called "begin.txt":
"AULLAH1" "01/07/2010 15:28 " "55621454" "123456" "123456.00"
"USERNAME" "7/3/2010 6:21 PM" "55621454" "123456" "123456.00"
"AULLAH1" "07/07/2010 15:05 " "55621454" "189450" "123456.00"
"SUPREMEGAMER" "7/8/2010 6:42 PM" "55621454" "123456" "123456.00"
If a person types into the HTML form "AULLAH1", I'd like the php script to grab the last "AULLAH1" entry in the text file (e.g. It should grab the third line and not the first, as the third line is the last entry to contain the text "AULLAH1"). Also with that, when a person types in a specific text, it shouldn't simply grab the document or the text, it should grab the whole line: "AULLAH1" "07/07/2010 15:05 " "55621454" "189450" "123456.00" and place it into a php variable, maybe something like "$grabbed"? If possible at all.
All assistance is appreciated and I look fo开发者_开发问答rward to your replies; thank you. :) If I didn't explain anything clearly and/or you'd like me to explain in more detail, please reply. :)
Thank you.
You can use SplFileObject
and iterate over the file line by line.
Please note that iterating over the file is much more memory efficient than using file()
or file_get_contents()
because it does not read the entire file content into an array or a variable.
$username = 'AULLAH1';
$file = new SplFileObject("data.csv");
$grabbed = FALSE;
while (!$file->eof()) {
$data = $file->fgetcsv(' ');
if($data[0] === $username) {
$grabbed = $file->current();
}
}
echo $grabbed;
Because fgetcsv()
takes into account delimiters, enclosures and escape characters when parsing the line, it is not exactly fast though. If you have to parse a couple hundred or thousand lines this way, make sure you actually have the need for it.
An alternative would be to just check if the current line contains the username string somewhere. In the file format you show in the question, this would be feasible because the remaining fields contain digits, so there cannot be any false positives:
$username = 'AULLAH1';
$file = new SplFileObject("data.txt");
$grabbed = FALSE;
foreach($file as $line) {
if(strpos($line, $username) !== FALSE) {
$grabbed = $line;
}
}
echo $grabbed;
If you want to make sure the $username was found at position 1, change the if
condition to test for === 1
.
If, for some reason, you want to have all lines where the username occurs, you can write a custom FilterIterator to iterate over the file contents, e.g.
class UsernameFilter extends FilterIterator
{
protected $_username;
public function __construct(Iterator $iterator, $username)
{
$this->_username = $username;
parent::__construct($iterator);
}
public function accept()
{
return strpos($this->current(), $this->_username) !== FALSE;
}
}
Then you can simply use foreach
. The FilterIterator will pass each line to accept()
and only those lines for which it returns TRUE are actually used.
$filteredLines = new UsernameFilter(new SplFileObject('data.txt'), 'AULLAH1');
foreach($filteredLines as $line) {
echo $line;
}
The above would output
"AULLAH1" "01/07/2010 15:28 " "55621454" "123456" "123456.00"
"AULLAH1" "07/07/2010 15:05 " "55621454" "189450" "123456.00"
If you want these lines in an array, you can do
$lines = iterator_to_array($filteredLines);
and to look at the last item
echo end($lines);
i would not use a text file to store credentials but if you must atleast change the format of the text file to a CSV layout
have it like this
AULLAH1,01/07/2010 15:28,55621454,123456,123456.00
USERNAME,7/3/2010 6:21 PM,55621454,123456,123456.00
AULLAH1" "07/07/2010 15:05 " "55621454" "189450" "123456.00
SUPREMEGAMER,7/8/2010 6:42 PM,55621454,123456,123456.00
read the file line my line in PHP
<?php
$lines = file('begin.txt');
foreach($lines as $line)
{
if(preg_match('/(?<username>.*?),(?<ts>.*?),(?<id_1>.*?),(?<id_2>.*?),(?<balance>.*?)/',$line,$parts))
{
if($_POST['username'] == $parts['username'])
{
//Do what you need here.
break;
}
}
}
?>
you could also use explode witch is faster but is limited to auto generate keys forthe array!
<?php
$lines = file('begin.txt');
foreach($lines as $line)
{
$parts = explode(',',$line);
if($_POST['username'] == $parts[0])
{
//Do what you need here.
break;
}
}
?>
Using preg_match_all()
could be a solution:
$file = file_get_contents($filename);
$username = 'ALLUAH1';
preg_match_all('/^"'.preg_quote($username, '/').'".*$/m', $file, $matches);
// Note that the '/m' flag of the regex makes '^' and '$' match
// the beginning and end of each line.
// Also note that I am using preg_quote() to escape special regex characters
$grabbed = array_pop($matches[0]);
Now $grabbed
should hold the value of the last line of that user.
Related links:
preg_match_all()
preg_quote()
array_pop()
This is the shortest I can come up with:
$list = file_get_contents('data.txt');
echo strstr(substr($list, strrpos($list, 'AULLAH1')-1), PHP_EOL, TRUE);
This will read the file into memory. Then it finds the offset of the last occurence of the string 'AULLAH1'. Everything one letter before this occurence up to the next newline character will be returned.
This requires PHP5.3 due to the strstr()
's third argument and requires more memory than the iterator solution above. Depending on your newlines, you might have to change PHP_EOL to the newline chars used in the file.
This is the absolute simplest way I can think of implementing this. This method simply runs through the lines of the file in reverse order, and so does not need to search each and every line. It also assumes the username, wrapped in double quotes, is the very first thing on each line of the input file.
$username = "AULLAH1";
$input_file = file("begin.txt");
$grabbed = "";
for($i = count($input_file) - 1; $i >= 0; $i--)
{
// Note: Exactly zero (string starts the line), NOT "FALSE"
if(strpos($input_file[$i], "\"$username\"") === 0)
{
$grabbed = $input_file[$i];
break;
}
}
精彩评论