Zgaduję, że to fgety, ale nie mogę znaleźć konkretnej składni. Próbuję odczytać (w łańcuchu, który uważam za łatwiejszy) ostatnią linię dodaną do pliku dziennika.PHP - Zwracanie ostatniej linii w pliku?
Odpowiedz
Najprostszym rozwiązaniem jest po prostu naiwny:
$file = "/path/to/file";
$data = file($file);
$line = $data[count($data)-1];
Choć Spowoduje to załadowanie całego pliku do pamięci. Prawdopodobnie problem (lub nie). Lepszym rozwiązaniem jest to:
$file = escapeshellarg($file); // for the security concious (should be everyone!)
$line = `tail -n 1 $file`;
albo trzeba odczytać plik linia po linii i zapisać ostatnią odczytaną linię do niego dostać.
Lub jeśli na Unix/Linux można rozważyć użycie ogon poleceń powłoki
tail -n 1 filename
To wygląda na to jest to, czego szukasz:
tekkie.flashbit.net: Tail functionality in PHP
Realizuje funkcję używa fseek() z ujemnym indeksem do zwijania pliku od końca. Możesz określić, ile wierszy chcesz zwrócić.
Kod jest również dostępny as a Gist on 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;
}
Iiinteresting ... ale całkowicie bezużyteczne obok znacznie łatwiejszego sposobu tylko ostrzał emisyjnej nad do ogona (chyba, że są naprawdę na bardzo poważnie przepracowany serwerze) –
„kompletnie bezużyteczny” jest nieco szorstki – Tomalak
Ok, być może niewiele ... nadal byłbym niechętny do korzystania z tego, chyba że ktoś mógłby mi udowodnić, że używanie 'tail' było faktycznie przyczyną wąskich gardeł, a nie operacji na dużych bazach danych. –
Jeśli chcesz odczytać pliku linia po linii funkcja file
odczytuje zawartość pliku, wiersz po wierszu i zwraca każdy wiersz jako element szyk.
Więc można zrobić coś prostego, jak:
$lines = file('log.txt');
$lastLine = array_pop($lines);
Naprawdę? W przypadku pliku dziennika o wielu megabajtach, którego 99,99% nie jest dla mnie interesujące, starałbym się uniknąć ładowania go do tablicy tylko po to, aby natychmiast go wyrzucić. – Tomalak
Nie zaprzeczając, że jest to nieefektywne, ale działa; i kto wie, jak długo trwa ten plik? Chciałbym użyć polecenia ogon w moim środowisku, ale WiseDonkey nie określił żadnego. Ale fajna funkcja, z którą się łączyłeś. –
file() i file_get_contents() są świetnymi funkcjami manipulowania plikami, szczególnie jeśli wiesz, że pliki, których to dotyczy, są stosunkowo małe i chcesz je szybko i łatwo zrobić. –
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);
To jest lepsze, ponieważ nie załadować cały plik do pamięci ...
zestaw YOUR_EOL do poprawnych zakończeń linii, jeśli używasz tego samego endingi linii jako domyślne zakończenia linii systemu operacyjnego, w którym znajduje się twój skrypt, możesz użyć stałej PHP_EOL.
Ten przyzwyczajenie złamać pliku o 1 lub 0 linii.
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;
}
function seekLastLine($f) {
$pos = -2;
do {
fseek($f, $pos--, SEEK_END);
$ch = fgetc($f);
} while ($ch != "\n");
}
-2
ponieważ ostatni char może być \n
... Dlaczego po prostu czytać ostatnią linię?
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);
Bo tego właśnie potrzebował PO? lol – dtbarne
@unique_stephen, twoja odpowiedź jest wadliwa. PHP fseek zwraca 0 dla sukcesu i -1 dla niepowodzenia. Przechowywanie wyniku w $ początku (sic), a później użycie go w filtrze dla ftell() jest niepoprawne. Gdyby moja reputacja była wyższa, oddałbym głos i zostawiłam komentarz. Oto zmodyfikowana wersja funkcji 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;
}
UWAGA: fseek PHP nie potrafi dążyć do końca plików większych niż PHP_MAX_INT który jest 32-bitową nawet na 64-bitowych plików binarnych.
Nie zapewnia to odpowiedzi na pytanie. Gdy masz już wystarczającą [reputację] (https://stackoverflow.com/help/whats-reputation), będziesz mógł [komentować dowolny wpis] (https://stackoverflow.com/help/privileges/comment); zamiast tego [dostarczaj odpowiedzi, które nie wymagają wyjaśnień od pytającego] (https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can- i-do-zamiast). - [Z recenzji] (/ opinia/niskiej jakości-posts/18923154) –
Tak, istnieją już odpowiedzi na pytanie.Problem polegający na tym, że nie można dodać komentarza do odpowiedzi, należy rozwiązać, jeśli nie chcesz, aby moja odpowiedź została dodana jako komentarz. Będę edytować odpowiedź, aby podać poprawną wersję odpowiedzi @ unique_stephen. – Earnie
na miejscu, dzięki Matthew – waxical
FYI, użyłem ogona ... – waxical
Zauważ, że jest to bardzo niebezpieczne, chyba że używasz escapeshellarg(): http://de.php.net/manual/en/function.escapeshellarg.php – soulmerge