filename = $filename; $this->filepath = DIR_LOGS . $filename; if(!is_dir(DIR_LOGS)){ $old = umask(0); mkdir(DIR_LOGS, 0764, true); umask($old); } if(!is_writable(DIR_LOGS)){ trigger_error('The '.DIR_LOGS.' folder must to be writeable!', E_USER_ERROR); } $this->fileobj = fopen($this->filepath, 'a+'); return; } /** * Write the error message in the log file * * @param string $message * @return int|false * @since 1.0.0 */ public function write($message) { return fwrite($this->fileobj, date('Y-m-d G:i:s') . ' - ' . print_r($message, true)." | ".$_SERVER['REQUEST_URI'] . PHP_EOL); } /** * Remove object from memory * * @since 1.0.0 * @return void */ public function __destruct() { fclose($this->fileobj); } /** * Return the log file name * * @since 2.0.0 * @return string */ public function getFileName() { return $this->filename; } /** * Return the log file path * * @since 2.0.0 * @return string */ public function getFilePath() { return $this->filepath; } /** * Return last lines of log archive * * @param string|null $filepath (optional) Path of file. Default is the log file. * @param int $lines (optional) Lines to be readed. Default value is 10. * @param bool $adaptive (optional) Default value is true. * @return false|string * @since 2.0.0 */ public function tail($filepath = null, int $lines = 10, bool $adaptive = true) { // Open file $f = @fopen(($filepath ?: $this->filepath), "rb"); if ($f === false) return false; // Sets buffer size if (!$adaptive) $buffer = 4096; else $buffer = ($lines < 2 ? 64 : ($lines < 10 ? 512 : 4096)); // Jump to last character fseek($f, -1, SEEK_END); // Read it and adjust line number if necessary // (Otherwise the result would be wrong if file doesn't end with a blank line) if (fread($f, 1) != "\n") $lines -= 1; // Start reading $output = ''; $chunk = ''; // While we would like more while (ftell($f) > 0 && $lines >= 0) { // Figure out how far back we should jump $seek = min(ftell($f), $buffer); // Do the jump (backwards, relative to where we are) fseek($f, -$seek, SEEK_CUR); // Read a chunk and prepend it to our output $output = ($chunk = fread($f, $seek)) . $output; // Jump back to where we started reading fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR); // Decrease our line counter $lines -= substr_count($chunk, "\n"); } // While we have too many lines // (Because of buffer size we might have read too many) while ($lines++ < 0) { // Find first newline and remove all text before that $output = substr($output, strpos($output, "\n") + 1); } // Close file and return fclose($f); return trim($output); } /** * Return first lines of log archive * * @param string|null $filepath (optional) Path of file. Default is the log file. * @param int $lines (optional) Lines to be readed. Default value is 10. * @param bool $adaptive (optional) Default value is true. * @return false|string * @since 2.0.0 */ public function head($filepath = null, int $lines = 10, bool $adaptive = true) { // Open file $f = @fopen(($filepath ?: $this->filepath), "rb"); if ($f === false) return false; // Sets buffer size /* if (!$adaptive) $buffer = 4096; else $buffer = ($lines < 2 ? 64 : ($lines < 10 ? 512 : 4096)); */ // Start reading $output = ''; while (($line = fgets($f)) !== false) { if (feof($f)) break; if ($lines-- == 0) break; $output .= $line . ""; } // Close file and return fclose($f); return trim($output); } }