【问题标题】:PHP file searchingPHP文件搜索
【发布时间】:2011-04-16 09:11:25
【问题描述】:

我需要使用 php 进行文件搜索,并且我使用 glob 进行文件名搜索,但我仍然需要在文件中搜索。

我有一个原型,位于tann98.vacau.com/file-search,但我需要关键字和建议。此外,它还需要查看文件内部才能找到匹配项。

有人对如何做这种事情有想法吗?

【问题讨论】:

标签: php file search


【解决方案1】:

一个非常基本的方法是将每个文件读入 PHP 并使用其中一个字符串搜索函数搜索它们。

//loop through all filenames and for each one:
$contents = file_get_contents($filename) ;
if (strpos($contents, $keyword) !== false) {
    //found a match!
}

但是,这是非常低效的,因为每次执行搜索时都必须读取和搜索该文件。

这就是为什么搜索引擎会为他们预先知道的整个文件创建索引,然后只在这些索引中查找搜索关键字。如果你想研究它,你需要一个单独的脚本(比如 indexer.php)来做这样的事情:

  • 遍历每个文件,获取其内容
  • 把它们分解成文字
  • 记录在该文件中找到的唯一单词
  • 将该记录存储在数据库或磁盘上的文件中

并让它不时运行以更新其索引。例如,它的索引可能如下所示:

$words = array(
    'mobile' => array('filename1.txt', 'filename2.txt'),
    'answer' => array('filename3.txt', 'filename5.txt', 'filename6.txt'),
    //...

);

然后,当您搜索某个关键字时,您只需要从索引文件或数据库中加载索引,然后查看该词在哪些文件名中找到。

if (isset($words[$keyword])) {
    echo "Found in: " . join(', ', $words[$keyword]) ;
}

你有一个非常简单的方法来做这样的事情。进一步,您可以将索引存储到数据库中,计算在每个文件中找到一个单词的次数以提供更相关的结果等等。

【讨论】:

  • 很好的解释! --- 如果它对您可用,您可以使用 cron 作业来更新索引,例如每天。 --- Cron 作业以预设的时间或间隔(tophostingdeals.com/glossary.php)在服务器上执行文件。
  • 那是我一开始想做的,但搜索需要是实时的。
  • @tann 带有索引和建议的实时搜索可能超出了您尝试做的范围。只需每隔几分钟或您希望更改文件的频率运行一次索引器,以便它始终拥有新的索引数据。
【解决方案2】:
if (preg_match('/pattern/', file_get_contents($file))) {
   echo "found pattern in $file\n";
}

【讨论】:

    【解决方案3】:

    将整个文件读入 php 中的变量? 认真的,加油! php是一种超文本脚本语言! 你会遇到内存错误和丑陋的其他事情...... 仅当您知道每个文件不超过数百千字节时才执行此操作...

    如果你想要性能,这里有一个oyu的解决方案:

    <?php
    $handle = popen('grep regex /path/to/file.txt', 'r');
    $output = fread($handle, 2096);
    pclose($handle);
    ?>
    

    利用外部 grep 实用程序。 您可以给一些开关来报告位置(偏移量)以查看找到匹配项的位置 像这样工作(这次使用 exec 而不是 popen 用于演示目的):

    <?php
    exec('grep "REGEX" /path/to/file.txt -b', $result);
    ?>
    

    这可能只适用于 linux ...

    如果您真的想在 php 中执行此操作,或者这对您不起作用,请不要使用 file_get_contents 或类似的东西,而是通过文件查找。大概是这样的:

    <?php
    $handle = @fopen("/tmp/inputfile.txt", "r");
    if ($handle) {
        while (!feof($handle)) {
            $buffer = fgets($handle, 4096);
    if (preg_match('/pattern/', $buffer)) {
       echo "found pattern in $buffer\n";
    }
        }
        fclose($handle);
    }
    ?>
    

    不是说缓冲区可以在 4095 字节处被切断... fgets 逐行读取,但您可以指定最大值。

    【讨论】:

      猜你喜欢
      • 2010-12-24
      • 1970-01-01
      • 1970-01-01
      • 2015-02-05
      • 2012-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多