PHP - 返回文件中的最后一行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1062716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 00:49:47  来源:igfitidea点击:

PHP - Returning the last line in a file?

phpsyntaxfreadfgets

提问by waxical

I'm guessing it's fgets, but I can't find the specific syntax. I'm trying to read out (in a string I'm thinking is easier) the last line added to a log file.

我猜是 fgets,但我找不到具体的语法。我试图读出(在我认为更容易的字符串中)添加到日志文件的最后一行。

回答by Matthew Scharley

The simplest naive solution is simply:

最简单的天真解决方案很简单:

$file = "/path/to/file";
$data = file($file);
$line = $data[count($data)-1];

Though, this WILL load the whole file into memory. Possibly a problem (or not). A better solution is this:

尽管如此,这会将整个文件加载到内存中。可能是一个问题(或不是)。更好的解决方案是这样的:

$file = escapeshellarg($file); // for the security concious (should be everyone!)
$line = `tail -n 1 $file`;

回答by Tomalak

This looks like it is what you are looking for:

这看起来就是你要找的:

tekkie.flashbit.net: Tail functionality in PHP

tekkie.flashbit.net:PHP 中的尾部功能

It implements a function that uses fseek() with a negative index to roll up the file from the end. You can define how many lines you want to be returned.

它实现了一个函数,该函数使用带有负索引的 fseek() 从末尾开始汇总文件。您可以定义要返回的行数。

The code also is available as a Gist on GitHub:

该代码也可作为 GitHub 上的 Gist 获得

// full path to text file
define("TEXT_FILE", "/home/www/default-error.log");
// number of lines to read from the end of file
define("LINES_COUNT", 10);


function read_file($file, $lines) {
    //global $fsize;
    $handle = fopen($file, "r");
    $linecounter = $lines;
    $pos = -2;
    $beginning = false;
    $text = array();
    while ($linecounter > 0) {
        $t = " ";
        while ($t != "\n") {
            if(fseek($handle, $pos, SEEK_END) == -1) {
                $beginning = true; 
                break; 
            }
            $t = fgetc($handle);
            $pos --;
        }
        $linecounter --;
        if ($beginning) {
            rewind($handle);
        }
        $text[$lines-$linecounter-1] = fgets($handle);
        if ($beginning) break;
    }
    fclose ($handle);
    return array_reverse($text);
}

$fsize = round(filesize(TEXT_FILE)/1024/1024,2);

echo "<strong>".TEXT_FILE."</strong>\n\n";
echo "File size is {$fsize} megabytes\n\n";
echo "Last ".LINES_COUNT." lines of the file:\n\n";

$lines = read_file(TEXT_FILE, LINES_COUNT);
foreach ($lines as $line) {
    echo $line;
}

回答by Jeroen Serpieters

define('YOUR_EOL', "\n");
$fp = fopen('yourfile.txt', 'r');

$pos = -1; $line = ''; $c = '';
do {
    $line = $c . $line;
    fseek($fp, $pos--, SEEK_END);
    $c = fgetc($fp);
} while ($c != YOUR_EOL);

echo $line;

fclose($fp);

This is better, since it does not load the complete file into memory...

这更好,因为它不会将完整的文件加载到内存中......

Set YOUR_EOL to your correct line endings, if you use the same line endings as the default line endings of the OS where your script resides, you could use the constant PHP_EOL.

将 YOUR_EOL 设置为正确的行尾,如果您使用与脚本所在操作系统的默认行尾相同的行尾,则可以使用常量 PHP_EOL。

回答by constantined

function seekLastLine($f) {
    $pos = -2;
    do {
        fseek($f, $pos--, SEEK_END);
        $ch = fgetc($f);
    } while ($ch != "\n");
}

-2because last char can be \n

-2因为最后一个字符可以是 \n

回答by jitter

You either have to read the file in line by line and save the last read line to get it.

您要么必须逐行读取文件并保存最后读取的行以获取它。

Or if on unix/linux you might consider using the shell command tail

或者,如果在 unix/linux 上,您可以考虑使用 shell 命令 tail

tail -n 1 filename

回答by Simon Harper

...Why just read the last line?

...为什么只看最后一行?

function readLines($fp, $num) {

    $line_count = 0; $line = ''; $pos = -1; $lines = array(); $c = '';

    while($line_count < $num) {
        $line = $c . $line; 
        fseek($fp, $pos--, SEEK_END);
        $c = fgetc($fp);
        if($c == "\n") { $line_count++; $lines[] = $line; $line = ''; $c = ''; }
    }   
    return $lines;
}

$filename = "content.txt";
$fp = @fopen($filename, "r");

print_r(readLines($fp, 2));

fclose($fp);

回答by unique_stephen

This one wont break for a 1 or 0 line file.

对于 1 或 0 行文件,此文件不会中断。

function readlastline($fileName)
{

       $fp = @fopen($fileName, "r");
       $begining = fseek($fp, 0);      
       $pos = -1;
       $t = " ";
       while ($t != "\n") {
             fseek($fp, $pos, SEEK_END);
             if(ftell($fp) == $begining){
              break;
             }
             $t = fgetc($fp);
             $pos = $pos - 1;
       }
       $t = fgets($fp);
       fclose($fp);
       return $t;
}

回答by Earnie

@unique_stephen, your answer is flawed. PHP fseek returns 0 for success and -1 for failure. Storing the result in $begining (sic) and then later using it in a filter for ftell() isn't correct. If my reputation were higher I would have voted you down and left a comment. Here is a modified version of unique_stephen's function.

@unique_stephen,您的回答有缺陷。PHP fseek 返回 0 表示成功,-1 表示失败。将结果存储在 $begining (sic) 中,然后在 ftell() 的过滤器中使用它是不正确的。如果我的声誉更高,我会投票给你并留下评论。这是 unique_stephen 函数的修改版本。

function readlastline($fileName)
{
    $fp = @fopen($fileName, "r");
    if (fseek($fp, 0) == -1)
        exit('Cannot seek to beginning of the file'); 
    $pos = -1;
    $t = " ";
    while ($t != "\n") {
        if (fseek($fp, $pos, SEEK_END) == -1)
            exit('Cannot seek to the end of the file');
        if (ftell($fp) == 0) {
            break;
        }
        $t = fgetc($fp);
        $pos = $pos - 1;
    }
    $t = fgets($fp);
    fclose($fp);
    return $t;
}

NOTE: PHP's fseek cannot manage to seek to the end of files larger than PHP_MAX_INT which is 32bit signed even on 64bit binaries.

注意:PHP 的 fseek 无法找到大于 PHP_MAX_INT 的文件末尾,即使在 64 位二进制文​​件上也是 32 位签名。

回答by Kieran Hall

If you want to read a file line by line the filefunction reads the contents of a file, line by line and returns each line as an element of an array.

如果要逐行读取文件,该file函数会逐行读取文件的内容,并将每一行作为数组的元素返回。

So you could do something simple like:

所以你可以做一些简单的事情,比如:

$lines    = file('log.txt');
$lastLine = array_pop($lines);