Вопрос по php – PHP - возвращение последней строки в файле?

15

Я догадываюсь, что это fgets, но я не могу найти конкретный синтаксис. Я пытаюсь зачитать (в строке, которая мне кажется проще) последнюю строку, добавленную в файл журнала.

Ваш Ответ

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

-2 потому что последний символ может быть\n

39

Самое простое наивное решение - это просто:

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

Тем не менее, это будет загружать весь файл в память. Возможно проблема (или нет). Лучшее решение это:

$file = escapeshellarg($file); // for the security concious (should be everyone!)
$line = `tail -n 1 $file`;
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededescapeshellargError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededde.php.net/manual/en/function.escapeshellarg.php
Error: User Rate Limit ExceededtailError: User Rate Limit Exceeded
1

... зачем просто читать последнюю строку?

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);
Error: User Rate Limit Exceeded
0

@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;
}

ПРИМЕЧАНИЕ. PHP fseek не удается найти конец файлов, размер которых превышает PHP_MAX_INT, который имеет 32-битную подпись даже в 64-битных двоичных файлах.

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededreputationError: User Rate Limit Exceededcomment on any postError: User Rate Limit Exceededprovide answers that don't require clarification from the asker. - From Review
0

Если вы хотите прочитать файл построчноfile Функция читает содержимое файла построчно и возвращает каждую строку как элемент массива.

Таким образом, вы можете сделать что-то простое, как:

$lines    = file('log.txt');
$lastLine = array_pop($lines);
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
3

Вы должны либо прочитать файл построчно и сохранить последнюю прочитанную строку, чтобы получить его.

Или, если в Unix / Linux, вы можете рассмотреть возможность использования команды оболочки хвоста

tail -n 1 filename
8
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);

Это лучше, так как он не загружает весь файл в память ...

Установите для YOUR_EOL правильные окончания строк, если вы используете те же окончания строк, что и окончания строк по умолчанию в ОС, где находится ваш скрипт, вы можете использовать константу PHP_EOL.

1

Этот не сломается для 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;
}
13

Похоже, это то, что вы ищете:

tekkie.flashbit.net: функциональность хвоста в PHP

Он реализует функцию, которая использует fseek () с отрицательным индексом, чтобы свернуть файл с конца. Вы можете определить, сколько строк вы хотите вернуть.

Код также доступенкак Gist на GitHub:

// 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;
}
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededifError: User Rate Limit Exceeded
Error: User Rate Limit ExceededtailError: User Rate Limit Exceeded

Похожие вопросы