PHP获取具有多行的打开文件句柄的最后一行

时间:2015-03-20 12:16:29

标签: php filehandle file-processing fgetc

这似乎应该是一件简单的事情,但是当我返回打开文件句柄的最后一行时,我在使用fgetc()时遇到了一些麻烦。我试图做的是返回写入句柄的最后一行,如果句柄只有一行,我有以下内容:

function getLastLineFromHandle($handle)
{

    $seeker = function($handle) use (&$seeker) {

        fseek($handle, -1, SEEK_CUR);

        return ftell($handle) ?
            $seeker($handle) :
            $handle;
    };

    return trim(fgets($seeker($handle)));
}

$handle = fopen('php://temp', 'w+');
fwrite($handle, 'Hello World'.PHP_EOL);

//prints Hello World
print getLastLineFromHandle($handle);

问题是当我有多行写入句柄时,在检查条件中添加fgetc()似乎不起作用,例如:

function getLastLineFromHandle($handle)
{

    $seeker = function($handle) use (&$seeker) {

        fseek($handle, -1, SEEK_CUR);

        return ftell($handle) && fgetc($handle) != PHP_EOL ?
            $seeker($handle) :
            $handle;
    };

    return trim(fgets($seeker($handle)));
}

如果多个行写入句柄并且fgetc($ handle)似乎每次返回相同的字符,则返回空白?

我确定有一些非常简单的事情我已经错过了,但任何指针都会很棒,因为这让我发疯了!

感谢。

1 个答案:

答案 0 :(得分:0)

发现上面示例中缺少的内容,结果是在开始时指针处出现了意外的行结束字符,因此移动一个位置解决了问题,例如:

function getLastLineFromHandle($handle)
{
    $seeker = function($handle) use (&$seeker) {
        fseek($handle, -2, SEEK_CUR);

        return ftell($handle) && fgetc($handle) != PHP_EOL ?
            $seeker($handle) :
            $handle;
    };

    return trim(fgets($seeker($handle)));
}

在探索这个问题时,我也发现了另一种做同样事情的方法,感谢@ TheMarlboroMan关于寻求最终结果的评论:

function getLastLineFromHandle($handle)
{
    $seeker = function($handle, $cur = -2, $line = '') use (&$seeker)
    {
        $char = '';
        if (fseek($handle, $cur, SEEK_END) != -1) {
            $char = fgetc($handle);
            $line = $char.$line;
        }

        return ftell($handle) > 0 && $char != PHP_EOL?
            $seeker($handle, $cur-1,$line) :
            $line;
    };

    return trim($seeker($handle));
}

这不是通过重构循环,但是它通过了与上面其他方法相同的测试。返回行字符串而不是文件句柄似乎有点麻烦,因为这是你期望的。

如果有人采用不同的方式,请将此设置为已解决但可以发表评论:)

相关问题