代码之家  ›  专栏  ›  技术社区  ›  Al.

高效的PHP平面文件搜索

  •  3
  • Al.  · 技术社区  · 17 年前

    我想将0到5000个IP地址存储在一个纯文本文件中,在顶部有一个不相关的头文件。像这样:

    Unrelated data
    Unrelated data
    ----SEPARATOR----
    1.2.3.4
    5.6.7.8
    9.1.2.3
    

    现在,我想知道“5.6.7.8”是否在使用PHP的文本文件中。我只加载过一个完整的文件并在内存中处理过它,但是我想知道是否有一种更有效的方法可以用PHP搜索文本文件。如果有,我只需要一个对/错。

    有人能发光吗?还是我要先加载整个文件?

    事先谢谢!

    7 回复  |  直到 15 年前
        1
  •  5
  •   cletus    17 年前

    5000不是很多记录。你可以很容易地做到:

    $addresses = explode("\n", file_get_contents('filename.txt'));
    

    手动搜索,会很快。

    如果您要存储更多的内容,我建议您将它们存储在一个专为此类内容设计的数据库中。但是对于5000人,我认为全负荷加上蛮力搜索是可以的。

    在遇到问题之前不要优化问题。没有必要过分复杂化你的解决方案。

        2
  •  1
  •   localshred    17 年前

    我不确定Perl的命令行工具是否需要加载整个文件来处理它,但是您可以执行类似的操作:

    <?php
    ...
    $result = system("perl -p -i -e '5\.6\.7\.8' yourfile.txt");
    if ($result)
        ....
    else
        ....
    ...
    ?>
    

    另一种选择是将IP存储在基于第一组或第二组的单独文件中:

    # 1.2.txt
    1.2.3.4
    1.2.3.5
    1.2.3.6
    ...
    
    # 5.6.txt
    5.6.7.8
    5.6.7.9
    5.6.7.10
    ...
    
    ... etc.
    

    这样就不必担心文件太大,将整个文件加载到内存中会导致性能损失。

        3
  •  0
  •   Cody Caughlan    17 年前

    你可以为它去壳和grep。

        4
  •  0
  •   Bart    17 年前

    你可以试试 fgets()

    它一行一行地读取文件。不过,我不确定这样做的效率有多高。我猜,如果IP位于文件的顶部,效率会更高;如果IP位于底部,效率会低于读取整个文件的效率。

        5
  •  0
  •   Phill Pafford    17 年前

    在Linux服务器上,可以将grep命令与backticks一起使用。类似:

    $searchFor = '5.6.7.8';
    $file      = '/path/to/file.txt';
    
    $grepCmd   = `grep $searchFor $file`;
    echo $grepCmd;
    
        6
  •  0
  •   shedd    17 年前

    我没有亲自测试过这一点,但在PHP手册中有一小段代码是为大型文件解析而编写的:

    http://www.php.net/manual/en/function.fgets.php#59393

    //File to be opened
    $file = "huge.file";
    //Open file (DON'T USE a+ pointer will be wrong!)
    $fp = fopen($file, 'r');
    //Read 16meg chunks
    $read = 16777216;
    //\n Marker
    $part = 0;
    
    while(!feof($fp)) {
        $rbuf = fread($fp, $read);
        for($i=$read;$i > 0 || $n == chr(10);$i--) {
            $n=substr($rbuf, $i, 1);
            if($n == chr(10))break;
            //If we are at the end of the file, just grab the rest and stop loop
            elseif(feof($fp)) {
                $i = $read;
                $buf = substr($rbuf, 0, $i+1);
                break;
            }
        }
        //This is the buffer we want to do stuff with, maybe thow to a function?
        $buf = substr($rbuf, 0, $i+1);
        //Point marker back to last \n point
        $part = ftell($fp)-($read-($i+1));
        fseek($fp, $part);
    }
    fclose($fp);
    

    这段代码是由原作者Hackajar Yahoo com编写的。

        7
  •  0
  •   Tanner Ottinger    15 年前

    是否尝试将当前IP与列出的IP文本文件进行比较?这个 无关数据 无论如何都不匹配。 所以只需在完整的文件内容上使用strpos(file_get_contents)。

    <?php
        $file = file_get_contents('data.txt');
        $pos = strpos($file, $_SERVER['REMOTE_ADDR']);
        if($pos === false) {
            echo "no match for $_SERVER[REMOTE_ADDR]";
        }
        else {
            echo "match for $_SERVER[REMOTE_ADDR]!";
        }
    ?>