3

有没有办法:

  1. 计算我的 small_db.php 中的行数(1 行 = 数据行)
  2. 告诉 PHP 将文件指针准确地移动到第 322 行的开头。(所以我可以从这一行获取 fgets() 数据)
  3. 告诉 PHP 返回行号或出现文本“Quick brown fox”的行的全部内容?

我知道还有另一种方法可以将文件的所有内容放在一个字符串中,但是如您所知,如果文件很大,那么该方法的时间和内存效率都会低下。

4

1 回答 1

14

首先,这里有一些基本变量:

$filename = 'small_db.php';
$linenum  = 322;
$needle = 'Quick brown fox';
  1. 如何计算文件中的行数?

    要快速轻松地执行此操作,请在使用count()以下命令打开文件后使用file()

    $count = count( file( $filename));
    

    但是,如果您的文件很大,这将使用大量内存,因为它必须将整个文件加载到内存中才能计算file(). 或者,您可以使用标准文件函数 、、 fopen()和,打开文件并逐行读取,同时保持计数,如下所示:feof()fgets()fclose()

    $count = 0;
    $fp = fopen( $filename, 'r');
    
    while( !feof( $fp)) {
        fgets( $fp);
        $count++;
    }
    
    fclose( $fp);
    
  2. 如何将文件指针移动到特定行号的开头?

    这最好使用SplFileObject类来实现。您使用正在打开的文件的文件名创建此类的新对象,然后用于seek()查找您选择的行号。然后,您可以使用key()显示行号和current()(或getCurrentLine()fgets())来获取该行的内容,如下所示:

    // Create a new object for the file
    $file = new SplFileObject( $filename);
    
    // Seek to to the specific line number
    $file->seek( $linenum);  
    
    // Print that line:
    echo 'Line #' . $file->key() . ' contains: ' . $file->current();
    
  3. 如何返回出现特定针的行号或行的全部内容?

    据我所知,没有内置的 PHP 函数/方法可以做到这一点。您将需要使用类似于此函数的东西自己解析它,该函数检查文件中的每一行,由其文件指针给出$fp,针对特定的区分大小写的$needle使用strpos()(您可以stripos()用于不区分大小写的搜索):

    function find_in_file( $fp, $needle) {
        rewind( $fp); // Or: fseek($fp, 0);
    
        $line_number = 0;
    
        while( !feof( $fp)) {
            $line = fgets( $fp);
            if( !( strpos( $line, $needle) === false)) {
                break;
            }
            $line_number++;
        }
    
        return feof( $fp) ? null : array( 
            'line_number' => $line_number,
            'line' => fgets( $fp)
        );
    }
    

    您需要像这样调用此函数:

    $fp = fopen( $filename, 'r');
    $return = find_in_file( $fp, $needle);
    if( !is_null( $return)) {
        echo 'Found ' . $needle . ' in line #' . $return['line_number'] . "\n";
        echo 'That line contains: ' . $return['line'];
    }
    fclose( $fp);
    
于 2012-06-23T16:12:11.273 回答