Annotation of php/tail.class.php, revision 1.1
1.1 ! as 1: <?php
! 2:
! 3: /**
! 4: * Tail
! 5: *
! 6: * liesst eine Datei Zeilenweise aus
! 7: * und wartet auf aenderungen.
! 8: *
! 9: * @author Aron Schlesinger <as@paefchen.net>
! 10: * @version 1.0
! 11: * @license BSDL
! 12: * @php 5
! 13: * @cvs $paefchen$
! 14: *
! 15: * Example:
! 16: * $tail = new Tail('/var/log/access.log', 20);
! 17: * $tail->go();
! 18: * if ($tail->error())
! 19: * die($tail->getError());
! 20: **/
! 21:
! 22: class Tail {
! 23:
! 24: private $fh;
! 25: private $file;
! 26: private $linelength;
! 27: private $error = '';
! 28:
! 29:
! 30: /**
! 31: * __construct
! 32: *
! 33: * constructer, pruefft ob die Datei lesbar ist und setzt
! 34: * oefnet die Datei und setzt den Zeiger an die richtige stelle.
! 35: *
! 36: * @public
! 37: *
! 38: * @para file string Datei die gelesen werden soll
! 39: * @para lines int Zeilen die vom ende gelsen werden sollen.
! 40: * @para linelength int Max. laenge einer Zeile
! 41: **/
! 42: public function __construct($file, $lines = 5, $linelength = 1014) {
! 43: $this->open($file);
! 44: if (! $this->error())
! 45: $this->setLine($lines);
! 46: $this->linelength = (int)$linelength;
! 47: }
! 48:
! 49:
! 50: /**
! 51: * __destruct
! 52: *
! 53: * destructer, schliesst die Datei
! 54: *
! 55: * @public
! 56: **/
! 57: public function __destruct() {
! 58: @fclose($this->fh);
! 59: }
! 60:
! 61:
! 62: /**
! 63: * line
! 64: *
! 65: * liesst und wartet auf Zeilen
! 66: *
! 67: * @public
! 68: * @return string zeile
! 69: **/
! 70: public function line() {
! 71: if ($this->error())
! 72: return false;
! 73:
! 74: $line = '';
! 75: while (true) {
! 76: clearstatcache();
! 77: if (ftell($this->fh) == filesize($this->file))
! 78: sleep(1);
! 79: else {
! 80: $c = fgetc($this->fh);
! 81: if (strlen($line) <= $this->linelength)
! 82: $line .= $c;
! 83: if ($c == "\n")
! 84: break;
! 85: }
! 86: }
! 87: return $line;
! 88: }
! 89:
! 90:
! 91: /**
! 92: * open
! 93: *
! 94: * oeffnet eine Datei
! 95: *
! 96: * @private
! 97: * @para file string Datei die geoeffnet werden soll.
! 98: * @return bool
! 99: **/
! 100: private function open($file) {
! 101: if (! is_readable($file)) {
! 102: $this->error = sprintf('File %s not readable', $file);
! 103: return false;
! 104: }
! 105:
! 106: $this->fh = @fopen($file, 'r');
! 107: if (! $this->fh) {
! 108: $this->error = sprintf('fopen() make error on file %s', $file);
! 109: return false;
! 110: }
! 111:
! 112: $this->file = $file;
! 113: }
! 114:
! 115:
! 116: /**
! 117: * setLine
! 118: *
! 119: * setzt den Zeiger vom ende aus gesehen
! 120: * auf dem anfang der gewuenschte Zeile
! 121: *
! 122: * @private
! 123: * @para line int Zeile von hinten aus
! 124: * @return bool
! 125: **/
! 126: private function setLine($line) {
! 127: fseek($this->fh, -1, SEEK_END);
! 128: $p = ftell($this->fh);
! 129:
! 130: while ($line > 0) {
! 131: if ($p === 0)
! 132: break;
! 133: fseek($this->fh, --$p, SEEK_SET);
! 134: if (fgetc($this->fh) == "\n")
! 135: $line--;
! 136: }
! 137: }
! 138:
! 139:
! 140: /**
! 141: * go
! 142: *
! 143: * @public
! 144: **/
! 145: public function go() {
! 146: if ($this->error())
! 147: return false;
! 148:
! 149: if (isset($_SERVER['REQUEST_METHOD'])) {
! 150: set_time_limit(0);
! 151: header('Content-type: text/plain');
! 152: header('Cache-Control: no-store, no-cache');
! 153: }
! 154:
! 155: ob_implicit_flush(1);
! 156:
! 157: while ($line = $this->line()) {
! 158: if (isset($_SERVER['REQUEST_METHOD'])
! 159: && connection_status() > 0)
! 160: exit;
! 161:
! 162: print $line;
! 163: }
! 164: }
! 165:
! 166:
! 167: /* Error Methods */
! 168: public function error() { return empty($this->error) ? false : true; }
! 169: public function getError() { return $this->error; }
! 170: }
! 171:
! 172:
! 173:
! 174: ?>