Если вам разрешено выполнять команды оболочки в среде (и при условии, что вы используете свой сценарий на * Никс), можно вызвать команду родной Grep рекурсивно. Это даст вам самые быстрые результаты.
$contents_list = array("xyz","abc","hello");
$path = "/tmp/";
$pattern = implode('\|', $contents_list) ;
$command = "grep -r '$pattern' $path";
$output = array();
exec($command, $output);
foreach ($output as $match) {
echo $match . '\n';
}
Если disable_functions
директива действует, и вы не можете позвонить Grep, вы можете использовать подход с RecursiveDirectoryIterator
и чтение строки файлов по линии, используя StrPos на каждой строке. Обратите внимание: strpos
требует строгой проверки равенства (используйте !== false
вместо != false
), иначе вы пропустите совпадения в начале строки.
Немного более быстрый способ - использовать глобус, чтобы получить список файлов, и сразу же прочитать эти файлы, а не сканировать их по строкам. Согласно моим тестам, этот подход даст вам преимущество 30-35% времени по сравнению с вашим.
function recursiveDirList($dir, $prefix = '') {
$dir = rtrim($dir, '/');
$result = array();
foreach (glob("$dir/*", GLOB_MARK) as &$f) {
if (substr($f, -1) === '/') {
$result = array_merge($result, recursiveDirList($f, $prefix . basename($f) . '/'));
} else {
$result[] = $prefix . basename($f);
}
}
return $result;
}
$files = recursiveDirList($path);
foreach ($files as $filename) {
$file_content = file($path . '/' . $filename);
foreach ($file_content as $line) {
foreach($contents_list as $content) {
if(strpos($line, $content) !== false) {
echo $line . '\n';
}
}
}
}
Кредит на рекурсивной функции Глоб переходит к http://proger.i-forge.net/3_ways_to_recursively_list_all_files_in_a_directory/Opc
Подводя итог с точки зрения производительности вы следующие рейтинги (результаты в секундах для Фарли большой каталог, содержащий ~ 1200 файлов recusively, используя два общие текстовые шаблоны): GREP
- вызова через Exec() - 2.2015s
- использование рекурсивной
glob
и чтение файлов с file()
- 9.4443s
- использование
RecursiveDirectoryIterator
и читать файлы с readline()
- 15.1183s
, что о 'scandir' – zzlalani
Был аналогичный вопрос здесь: http://stackoverflow.com/questions/10663641/grep-with-f-like -in-php Может ли это помочь? – ErnestV