Спасибо, что нашли время, чтобы прочитать это, и я буду признателен за каждый ответ, не отвечающий за качество контента. 🙂
Я пытаюсь создать php-скрипт, который ищет текстовый файл для определенного текста. Человек вводит конкретный текст в форме HTML, а скрипт php должен искать этот текст в текстовом файле.
Значение поля ввода HTML-формы – это «имя пользователя» и внутри документа php переменная «$ username» – это введенные данные, пример, показанный ниже:
$username = $_POST['username'];
Текстовый файл ниже называется «begin.txt»:
"AULLAH1" "01/07/2010 15:28" "55621454" "123456" "123456.00"
"USERNAME" "07.07.2010 18:21" "55621454" "123456" "123456.00"
"AULLAH1" "07/07/2010 15:05" "55621454" "189450" "123456.00"
"SUPREMEGAMER" "8/8/2010 6:42 PM" "55621454" "123456" "123456.00"
Если человек вводит в HTML-форму «AULLAH1», я бы хотел, чтобы php-скрипт захватил последнюю запись «AULLAH1» в текстовом файле (например, он должен захватить третью строку, а не первую, так как третья строка последняя запись должна содержать текст «AULLAH1»). Кроме того, когда человек вводит конкретный текст, он не должен просто захватывать документ или текст, он должен захватить всю строку: «AULLAH1» «07/07/2010 15:05» «55621454» «189450 «123456.00» и поместите его в переменную php, возможно, что-то вроде «$ grabbed»? Если возможно вообще.
Приветствуется всякая помощь, и я с нетерпением жду ваших ответов; Спасибо. 🙂 Если бы я не объяснил ничего ясно и / или вы бы хотели, чтобы я объяснил более подробно, ответьте. 🙂
Спасибо.
Вы можете использовать SplFileObject
и перебирать файл по SplFileObject
.
Обратите внимание, что итерация по файлу намного эффективнее с точки зрения памяти, чем использование file()
или file_get_contents()
поскольку оно не считывает весь контент файла в массив или переменную.
$username = 'AULLAH1'; $file = new SplFileObject("data.csv"); $grabbed = FALSE; while (!$file->eof()) { $data = $file->fgetcsv(' '); if($data[0] === $username) { $grabbed = $file->current(); } } echo $grabbed;
Поскольку fgetcsv()
учитывает разделители, вложения и escape-символы при разборе строки, это не совсем быстро. Если вам нужно проанализировать пару сотен или тысяч строк таким образом, убедитесь, что у вас действительно есть необходимость в этом.
Альтернативой было бы просто проверить, содержит ли текущая строка строку имени пользователя. В формате файла, который вы видите в вопросе, это было бы возможно, потому что остальные поля содержат цифры, поэтому не может быть никаких ложных срабатываний:
$username = 'AULLAH1'; $file = new SplFileObject("data.txt"); $grabbed = FALSE; foreach($file as $line) { if(strpos($line, $username) !== FALSE) { $grabbed = $line; } } echo $grabbed;
Если вы хотите убедиться, что имя пользователя $ было найдено в позиции 1, измените условие if
для проверки на === 1
.
Если по какой-то причине вы хотите иметь все строки, в которых происходит имя пользователя, вы можете написать собственный фильтр FilterIterator для перебора содержимого файла, например
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; } }
Тогда вы можете просто использовать foreach
. FilterIterator передает каждую строку accept()
и фактически используются только те строки, для которых он возвращает TRUE.
$filteredLines = new UsernameFilter(new SplFileObject('data.txt'), 'AULLAH1'); foreach($filteredLines as $line) { echo $line; }
Вышеприведенный результат
"AULLAH1" "01/07/2010 15:28 " "55621454" "123456" "123456.00" "AULLAH1" "07/07/2010 15:05 " "55621454" "189450" "123456.00"
Если вам нужны эти строки в массиве, вы можете сделать
$lines = iterator_to_array($filteredLines);
и посмотреть на последний элемент
echo end($lines);
я бы не использовал текстовый файл для хранения учетных данных, но если вы должны изменить формат текстового файла на формат CSV
пусть это так
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
прочитайте строку строки моей строки в 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; } } } ?>
вы также можете использовать Explode Witch быстрее, но ограничено автоматическим генерированием ключей для массива!
<?php $lines = file('begin.txt'); foreach($lines as $line) { $parts = explode(',',$line); if($_POST['username'] == $parts[0]) { //Do what you need here. break; } } ?>
Использование preg_match_all()
может быть решением:
$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]);
Теперь $grabbed
должен содержать значение последней строки этого пользователя.
Ссылки по теме:
preg_match_all()
preg_quote()
array_pop()
Это самое короткое, что я могу придумать:
$list = file_get_contents('data.txt'); echo strstr(substr($list, strrpos($list, 'AULLAH1')-1), PHP_EOL, TRUE);
Это прочитает файл в памяти. Затем он находит смещение последнего появления строки «AULLAH1». Будет возвращена вся одна буква до этого появления до следующего символа новой строки.
Для этого требуется PHP5.3 из-за третьего аргумента strstr()
и требуется больше памяти, чем вышеупомянутое выше. В зависимости от ваших новых строк вам может потребоваться изменить PHP_EOL на символы новой строки, используемые в файле.
Это самый простой способ, который я могу придумать для реализации этого. Этот метод просто проходит через строки файла в обратном порядке, и поэтому не нужно искать каждую строку. Он также предполагает, что имя пользователя, заключенное в двойные кавычки, является самым первым в каждой строке входного файла.
$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; } }