* @version 1.0 * @license BSDL * @php 5 * @cvs $paefchen$ * * Example: * $tail = new Tail('/var/log/access.log', 20); * $tail->go(); * if ($tail->error()) * die($tail->getError()); **/ class Tail { private $fh; private $file; private $linelength; private $error = ''; /** * __construct * * constructer, pruefft ob die Datei lesbar ist und setzt * oefnet die Datei und setzt den Zeiger an die richtige stelle. * * @public * * @para file string Datei die gelesen werden soll * @para lines int Zeilen die vom ende gelsen werden sollen. * @para linelength int Max. laenge einer Zeile **/ public function __construct($file, $lines = 5, $linelength = 1014) { $this->open($file); if (! $this->error()) $this->setLine($lines); $this->linelength = (int)$linelength; } /** * __destruct * * destructer, schliesst die Datei * * @public **/ public function __destruct() { @fclose($this->fh); } /** * line * * liesst und wartet auf Zeilen * * @public * @return string zeile **/ public function line() { if ($this->error()) return false; $line = ''; while (true) { clearstatcache(); if (ftell($this->fh) == filesize($this->file)) sleep(1); else { $c = fgetc($this->fh); if (strlen($line) <= $this->linelength) $line .= $c; if ($c == "\n") break; } } return $line; } /** * open * * oeffnet eine Datei * * @private * @para file string Datei die geoeffnet werden soll. * @return bool **/ private function open($file) { if (! is_readable($file)) { $this->error = sprintf('File %s not readable', $file); return false; } $this->fh = @fopen($file, 'r'); if (! $this->fh) { $this->error = sprintf('fopen() make error on file %s', $file); return false; } $this->file = $file; } /** * setLine * * setzt den Zeiger vom ende aus gesehen * auf dem anfang der gewuenschte Zeile * * @private * @para line int Zeile von hinten aus * @return bool **/ private function setLine($line) { fseek($this->fh, -1, SEEK_END); $p = ftell($this->fh); while ($line > 0) { if ($p === 0) break; fseek($this->fh, --$p, SEEK_SET); if (fgetc($this->fh) == "\n") $line--; } } /** * go * * @public **/ public function go() { if ($this->error()) return false; if (isset($_SERVER['REQUEST_METHOD'])) { set_time_limit(0); header('Content-type: text/plain'); header('Cache-Control: no-store, no-cache'); } ob_implicit_flush(1); while ($line = $this->line()) { if (isset($_SERVER['REQUEST_METHOD']) && connection_status() > 0) exit; print $line; } } /* Error Methods */ public function error() { return empty($this->error) ? false : true; } public function getError() { return $this->error; } } ?>