Pregunta

Me supongo que es fgets, pero no puedo encontrar la sintaxis específica. Estoy tratando de leer (en una cadena que estoy pensando es más fácil) la última línea añadida a un archivo de registro.

¿Fue útil?

Solución

La solución más sencilla es simplemente ingenua:

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

Sin embargo, esto va a cargar todo el archivo en la memoria. Posiblemente un problema (o no). Una mejor solución es la siguiente:

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

Otros consejos

Esto parece que es lo que busca:

tekkie.flashbit.net: funcionalidad de cola en PHP

Implementa una función que utiliza fseek () con un índice negativo para enrollar el archivo desde el final. Puede definir el número de líneas que desea devolver.

El código también está disponible como Gist en 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;
}
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);

Esto es mejor, ya que no carga el archivo completo en la memoria ...

Conjunto YOUR_EOL a sus finales de línea correctos, si utiliza los mismos finales de línea como los finales de línea por defecto del sistema operativo en el que reside la secuencia de comandos, se puede utilizar el PHP_EOL constante.

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

-2 porque la última Char puede ser \n

Usted tiene que leer el archivo en línea por línea y guardar la última línea de lectura para conseguirlo.

O si en UNIX / Linux es posible considerar el uso de la cola de comandos shell

tail -n 1 filename

Éste no romperá para un archivo de 1 o 0 línea.

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

... ¿Por qué acaba de leer la última línea?

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);

Si quiere leer un archivo línea por línea de la file función lee el contenido de un archivo, línea por línea y devuelve cada línea como un elemento de una matriz.

Por lo que podría hacer algo tan simple como:

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

@unique_stephen, su respuesta es errónea. PHP fseek devuelve 0 para el éxito y -1 para el fracaso. Almacenando el resultado en $ inicio (sic) y, posteriormente, se utiliza en un filtro para ftell () no es correcta. Si mi reputación fueron mayores te habría votado abajo ya la izquierda un comentario. Aquí es una versión modificada de la función de 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;
}

NOTA: fseek de PHP no puede manejar a buscar hasta el final de archivos de más de 32 bits PHP_MAX_INT el que se firmó incluso en los binarios de 64 bits

.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top