0

PHP: поиск в текстовом файле и вывод целой строки

9

Я пытаюсь создать скрипт на PHP, который будет искать внутри текстового файла и выводить целую строку, в которой найдено соответствие.

У меня есть текстовый файл (.txt) с названием "numorder.txt", и в этом файле содержатся несколько строк данных, новые строки добавляются каждые 5 минут (с помощью cron job). Данные имеют следующий вид:

2 aullah1
7 name
12 username

Как мне создать PHP-скрипт, который будет искать значение "aullah1" и затем выводить всю строку, в которой оно содержится? (В результате должно быть выведено "2 aullah1", без кавычек).

Если что-то объяснено неясно или вам нужно больше деталей, пожалуйста, дайте знать в комментариях.

5 ответ(ов)

0

Конечно! Вот перевод ответа на вопрос на StackOverflow:


Вот пример на PHP, который показывает, как вывести все строки, содержащие заданное слово в текстовом файле:

<?php
$file = 'somefile.txt';  // Указываем файл для чтения
$searchfor = 'name';      // Слово для поиска

// Эта строка предотвращает парсинг браузером как HTML
header('Content-Type: text/plain');

// Получаем содержимое файла, предполагая, что файл доступен для чтения (и существует)
$contents = file_get_contents($file);

// Экранируем специальные символы в запросе
$pattern = preg_quote($searchfor, '/');

// Завершаем регулярное выражение, чтобы совпадать с целой строкой
$pattern = "/^.*$pattern.*\$/m";

// Ищем совпадения и сохраняем их в $matches
if (preg_match_all($pattern, $contents, $matches)) {
    echo "Найдены совпадения:\n";
    echo implode("\n", $matches[0]); // Выводим все найденные строки
} else {
    echo "Совпадений не найдено";
}

Этот код читает содержимое файла somefile.txt, ищет все строки, содержащие слово name, и выводит их. Если совпадений не найдётся, появляется сообщение об этом. Убедитесь, что файл существует и доступен для чтения, иначе код будет выдавать ошибку.

0

В вашем коде есть несколько моментов, которые стоит уточнить и исправить.

  1. Открытие файла: Метод fclose используется для закрытия файлового дескриптора, но в вашем случае вы не открываете файл с помощью fopen. Используйте file_get_contents, чтобы читать содержимое файла, но не следует в этом контексте вызывать fclose.

  2. Безопасность: Обратите внимание на безопасность. Вы используете значение из $_GET, что может привести к уязвимостям, таким как XSS или инъекции. Рекомендуется валидировать и экранировать входные данные.

  3. Неправильное закрытие файла: Ваша строка fclose($file) будет вызывать ошибку, поскольку переменная $file — это не ресурс файла, а просто строка с именем файла.

Вот исправленный вариант вашего кода:

$searchfor = $_GET['keyword'] ?? ''; // Используем оператор ?? для установки значения по умолчанию
$file = 'users.txt';

$contents = file_get_contents($file);
if ($contents === false) {
    echo "Ошибка при чтении файла.";
    exit;
}

$pattern = preg_quote($searchfor, '/');
$pattern = "/^.*$pattern.*\$/m";

if (preg_match_all($pattern, $contents, $matches)) {
    echo "Найденные совпадения:<br />";
    echo implode("<br />", $matches[0]);
} else {
    echo "Совпадений не найдено";
}

Объяснение изменений:

  • Я добавил проверку на наличие или ошибку при чтении файла.
  • Устранил вызов fclose, так как он здесь не нужен.
  • Добавил установку значения по умолчанию для $searchfor, чтобы избежать ошибок, если keyword не передан в GET-запросе.

Обязательно проверьте входные данные на безопасность и корректность!

0

В вашем случае, возможно, будет лучше использовать system("grep \"$QUERY\""), так как ваш скрипт не будет особенно эффективным в любом случае. В противном случае вы можете ознакомиться с документацией по функции file(), которая показывает, как проходить по строкам файла, и использовать strstr() для поиска совпадений.

0

Один из способов сделать это — использовать регулярные выражения для поиска строки, содержащей определенное слово. Вот пример кода:

$needle = "blah";
$content = file_get_contents('file.txt');
preg_match('~^(.*'.$needle.'.*)$~', $content, $line);
echo $line[1];

Тем не менее, более оптимальным решением будет чтение файла построчно с помощью fopen() и fread() и использование strpos() для поиска искомого слова. Это поможет избежать проблем с производительностью при работе с большими файлами. Вот пример, как можно реализовать этот подход:

$needle = "blah";
$handle = fopen('file.txt', 'r');
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        if (strpos($line, $needle) !== false) {
            echo $line;
            break; // прерываем, если нашли первую подходящую строку
        }
    }
    fclose($handle);
} else {
    // Обработка ошибок открытия файла
    echo "Ошибка открытия файла.";
}

Такой подход обычно более эффективен, особенно для больших файлов, поскольку позволяет обрабатывать их по строкам и не загружать весь файл в память.

0

Ваш код немного модифицирован на основе упомянутого ответа и поддерживает несколько директорий и переменные ключевые слова через переменную GET. Если вам нужно реализовать это именно в этом формате, то вот пример, как можно это сделать:

if (isset($_GET["keyword"]) && isset($_GET["directory"])) {
    $searchfor = $_GET["keyword"];
    $directory = $_GET["directory"];
    
    // Устанавливаем заголовок, чтобы браузер не интерпретировал как HTML.
    header('Content-Type: text/plain');
    
    // Получаем список файлов .php в указанной директории
    foreach (glob($directory . '/*.php') as $file) { 
        // Проверяем, что файл читаем
        if (is_readable($file)) {
            // Получаем содержимое файла
            $contents = file_get_contents($file);
            
            // Экранируем специальные символы в запросе
            $pattern = preg_quote($searchfor, '/');
            // Завершаем регулярное выражение, соответствующее всей строке
            $pattern = "/^.*$pattern.*\$/m";
            
            // Ищем, и сохраняем все совпадения в $matches
            if (preg_match_all($pattern, $contents, $matches)) {
                echo "Найдены совпадения в файле: $file\n";
                echo implode("\n", $matches[0]);
                echo "\n\n";
            }
        }
    }
}

Объяснение:

  1. Проверка параметров GET: Мы проверяем, установлены ли keyword и directory.
  2. Формирование пути: Мы используем переменную $directory для поиска файлов в заданной директории, что дает возможность осуществлять поиск в разных каталогах.
  3. Чтение содержимого файлов: Убедимся, что файл читаем перед тем, как загружать его содержимое.
  4. Регулярные выражения: Формируем регулярное выражение таким образом, чтобы искать совпадения по всей строке.
  5. Вывод результатов: Если найдены совпадения, выводим сообщения с указанием файла и самими совпадениями.

Этот код позволит вам динамически искать в PHP-файлах с использованием переменных из GET-запроса, что делает его более универсальным и удобным для использования.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь