PHP – ¿Devolviendo la última línea en un archivo?

Supongo que es fgets, pero no puedo encontrar la syntax específica. Estoy intentando leer (en una cadena que estoy pensando que es más fácil) la última línea agregada a un archivo de registro.

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

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

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

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

Esto parece que es lo que estás buscando:

tekkie.flashbit.net: Funcionalidad de cola en PHP

Implementa una función que usa fseek () con un índice negativo para enrollar el archivo desde el final. Puede definir cuántas líneas 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 "".TEXT_FILE."\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 …

Establezca YOUR_EOL en las terminaciones de línea correctas, si usa las mismas terminaciones de línea que las terminaciones de línea predeterminadas del sistema operativo donde reside su secuencia de comandos, podría usar la constante PHP_EOL.

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

-2 porque el último char puede ser \n

O tiene que leer el archivo línea por línea y guardar la última línea de lectura para obtenerlo.

O si en Unix / Linux puede considerar usar la cola del comando de shell

 tail -n 1 filename 

Este no se romperá para un archivo de 1 o 0 líneas.

 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é solo lees 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 desea leer un archivo línea por línea, la función de file lee el contenido de un archivo, línea por línea, y devuelve cada línea como un elemento de una matriz.

Entonces podrías hacer algo simple como:

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

@unique_stephen, tu respuesta es defectuosa. PHP fseek devuelve 0 para el éxito y -1 para el fracaso. Almacenar el resultado en $ begining (sic) y luego usarlo en un filtro para ftell () no es correcto. Si mi reputación fuera más alta, te habría votado negativamente y habría dejado un comentario. Aquí hay 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 llegar al final de los archivos más grandes que PHP_MAX_INT que está firmado 32bit incluso en los binarios de 64 bits.