Nar*_*ari 12 php arrays recursion file-search
我是PHP编码的新手,我在寻找在字符串数组的所有目录上进行递归搜索的最快方法.
我这样做
$contents_list = array("xyz","abc","hello"); // this list can grow any size
$path = "/tmp/"; //user will give any path which can contain multi level sub directories
$dir = new RecursiveDirectoryIterator($path);
foreach(new RecursiveIteratorIterator($dir) as $filename => $file) {
$fd = fopen($file,'r');
if($fd) {
while(!feof($fd)) {
$line = fgets($fd);
foreach($contents_list as $content) {
if(strpos($line, $content) != false) {
echo $line."\n";
}
}
}
}
fclose($fd);
}
Run Code Online (Sandbox Code Playgroud)
在这里,我递归迭代所有目录,然后再次在每个文件上迭代内容数组进行搜索.
有没有更好的方法来进行搜索?请建议更快的替代方案.
谢谢
And*_*ázi 13
如果您被允许在您的环境中执行shell命令(并假设您在*nix上运行脚本),则可以递归调用本机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';
}
Run Code Online (Sandbox Code Playgroud)
如果disable_functions指令生效且你不能调用grep,你可以使用你的方法RecursiveDirectoryIterator和逐行读取文件,在每一行使用strpos.请注意,strpos需要严格的相等检查(使用!== false而不是!= false),否则您将跳过一行开头的匹配.
稍微快一点的方法是使用glob重新获取文件列表,并一次读取这些文件,而不是逐行扫描.根据我的测试,这种方法比你的方法有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';
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
递归glob函数的功劳归到http://proger.i-forge.net/3_ways_to_recursively_list_all_files_in_a_directory/Opc
总而言之,在性能方面你有以下排名(使用两种常见的文本模式,在一个包含~1200个文件的远程大型目录的结果中以秒为单位):
glob和读取文件file()- 9.4443sRecursiveDirectoryIterator和读取文件readline()- 15.1183s