我该如何在PHP中保存日志?是否有任何“神奇”的函数或库可以做到这一点?还是每次都需要使用
fopen
打开文件并将其转储到其中?我想将我的日志保存在文本文件中。谢谢!fopen
打开文件并将其转储到其中?我想将我的日志保存在文本文件中。谢谢!如果您不想使用自己的实现或只是进行fopen操作,可以使用内置函数error_log('要记录的字符串');
。这将把所需的字符串写入您的服务器软件的错误日志中。
error_log
php.ini设置配置默认记录器的设置:http://php.net/error-log - Powerlord我写了一个简单的类来实现这个功能,也许你会觉得它有用。
class Log
{
public function __construct($log_name,$page_name)
{
if(!file_exists('/your/directory/'.$log_name)){ $log_name='a_default_log.log'; }
$this->log_name=$log_name;
$this->app_id=uniqid();//give each process a unique ID for differentiation
$this->page_name=$page_name;
$this->log_file='/your/directory/'.$this->log_name;
$this->log=fopen($this->log_file,'a');
}
public function log_msg($msg)
{//the action
$log_line=join(' : ', array( date(DATE_RFC822), $this->page_name, $this->app_id, $msg ) );
fwrite($this->log, $log_line."\n");
}
function __destruct()
{//makes sure to close the file and write lines when the process ends.
$this->log_msg("Closing log");
fclose($this->log);
}
}
$log=new Log('file_name','my_php_page');
$log->log_msg('fizzy soda : 45 bubbles remaining per cubic centimeter');
error_log($msg, 3, $log_name);
非常复杂的版本。 - Powerlordmicrotime(1).(time()/147))
). - TCM<?
class Logger
{
private static function addEntry($str)
{
$handle = fopen('./services.log', 'a');
fwrite($handle, sprintf("%s %s\n", date('c'), $str));
fclose($handle);
}
public static function warn($str)
{
self::addEntry("WARNING $str");
}
public static function info($str)
{
self::addEntry("INFO $str");
}
public static function debug($str)
{
self::addEntry("DEBUG $str");
}
}
?>
<?php
require('Logger.php');
Logger::debug('test');
Logger::warn('bwah');
Logger::info('omg');
?>
Logger :: error()
),存储文件处理程序,这样每次想要记录日志时就不必重新打开它(即,在私有静态类范围变量中存储$handle
变量,并在运行addEntry()
时检查是否设置并运行fopen()
,如果没有设置则运行),或者更改记录日志的格式。最后一个回答是在2010年,需要更新一下。我与大家分享一下我在程序中使用的php类。
我采用了与上面@Sam-Bisbee
答案类似的方法,因此可以轻松添加新功能和函数,但我还使它更加灵活,适用于不同的程序/脚本。
我将我的类放在Logg.php
文件中,您也可以这样做。
<?php
class Logg
{
public static $fileName = 'new_log';
public static $filePath = '/';
public static $fileType = '.log';
public static function addInfo($logMsg, $fName = null, $fPath = null)
{
$fName = $fName ?: self::$fileName;
$fPath = $fPath ?: self::$filePath;
self::addData($logMsg, $fName, $fPath, ' | INFO |');
}
public static function addWarn($logMsg, $fName = null, $fPath = null)
{
$fName = $fName ?: self::$fileName;
$fPath = $fPath ?: self::$filePath;
self::addData($logMsg, $fName, $fPath, ' | WARNING |');
}
public static function addErr($logMsg, $fName = null, $fPath = null)
{
$fName = $fName ?: self::$fileName;
$fPath = $fPath ?: self::$filePath;
self::addData($logMsg, $fName, $fPath, ' | ERROR |');
}
public static function addConf($logMsg, $fName = null, $fPath = null)
{
$fName = $fName ?: self::$fileName;
$fPath = $fPath ?: self::$filePath;
self::addData($logMsg, $fName, $fPath, ' | CONFIG |');
}
private static function addData($logMsg, $fName, $fPath, $type)
{
$handle = fopen($fPath . $fName . self::$fileType, 'a');
if (gettype($logMsg) == 'array') {
if (count($logMsg)%2 == 0) {
$logText = '';
for ($i = 0; $i < count($logMsg); $i+=2) {
$logText .= str_pad($logMsg[$i], $logMsg[$i+1], " ", STR_PAD_BOTH).'|';
}
fwrite($handle, sprintf("| %s%s", date("Y-m-d H:i:s"), $type.$logText.PHP_EOL));
} else {
throw new Exception('Wrong arguments for Array-type log.');
}
} else {
fwrite($handle, sprintf("| %s%s", date("Y-m-d H:i:s"), $type.' '.$logMsg.PHP_EOL));
}
fclose($handle);
}
public static function addLine($lines = 1, $fName = null, $fPath = null)
{
$fName = $fName ?: self::$fileName;
$fPath = $fPath ?: self::$filePath;
$handle = fopen($fPath . $fName . self::$fileType, 'a');
fwrite($handle, str_repeat(PHP_EOL, $lines));
fclose($handle);
}
}
?>
包含类 - 指定日志文件的名称和路径:
<?php
require '/Logg.php';
//specifying logs file name and path - best do this right after include
Logg::$fileName = 'ExampleName_'.date("Y_m_d"); //if not specified, default value = 'new_log'
Logg::$filePath = 'C:/Apache24/htdocs/public_html/logs/'; //if not specified, default value = '/'
//Logging simple messages
Logg::addInfo("FooBar"); //sample information log message
Logg::addWarn("Sample warning"); //sample warning log message
Logg::addErr ("Sample error"); //sample error log message
Logg::addConf("Sample config log"); //sample config change log message
//Adding empty lines
Logg::addLine(); //adds empty line
Logg::addInfo("Log after empty line"); //some log
Logg::addLine(3); //adds 3 lines instead of one
Logg::addInfo("Log after 3 empty lines"); //some log
Array
(建议)代替 String
作为您的“日志信息”,就像下面的示例一样。这将使您的日志消息格式化为指定的长度,以使它们更易读:Logg::addLine();
Logg::addInfo(['Goo', 5]); //logs 'Goo' as char of length 5
Logg::addInfo(['', 10, 'Goo', 5]); //logs empty space of length 10 and a 'Goo' of length 5 after that
Logg::addInfo(['Foo', 10 , 'Bar', 5, 'Sample message with some length formatted to 75 chars', 75]); //more examples
Logg::addInfo(['FooBar', 10 , 'Baz', 5, 'Another sample message with different length formatted to 75 chars', 75]);
Logg::addLine();
Logg::addInfo(['Different message of length 65 - trying to format it to length 50', 50]); //in this case the message will keep it initial length so we wont be loosing any of the information we are logging
| 2021-08-31 11:28:52 | INFO | FooBar
| 2021-08-31 11:28:52 | WARNING | Sample warning
| 2021-08-31 11:28:52 | ERROR | Sample error
| 2021-08-31 11:28:52 | CONFIG | Sample config log
| 2021-08-31 11:28:52 | INFO | Log after empty line
| 2021-08-31 11:28:52 | INFO | Log after 3 empty lines
| 2021-08-31 11:28:52 | INFO | Goo |
| 2021-08-31 11:28:52 | INFO | | Goo |
| 2021-08-31 11:28:52 | INFO | Foo | Bar | Sample message with some length formatted to 75 chars |
| 2021-08-31 11:28:52 | INFO | FooBar | Baz | Another sample message with different length formatted to 75 chars |
| 2021-08-31 11:28:52 | INFO |Different message of length 65 - trying to format it to length 50|
可以通过更改我Logg类的$fileType
属性来更改为不同的文件类型。默认文件类型为".log"。
例如:
//changing file type, can be put after class include
Logg::$fileType = ".txt";
//logging some example messages
Logg::addInfo("Log message now in .txt file");
Logg::addWarn("Everything will be saved to this file from now on!");
| 2021-08-31 09:35:20 | INFO | Log message now in .txt file
| 2021-08-31 09:35:20 | WARNING | Everything will be saved to this file from now on!
每个公共的“添加”函数都有两个额外的参数 - 文件名和文件路径。指定这些参数将暂时覆盖先前指定的Logg::$fileName
和Logg::$filePath
类变量的值。
如果您想要将一些信息记录到具有不同名称或不同路径的文件中,但不想为程序中使用的每个日志更改文件路径或文件名,则这可能非常有用。
用法:
//Additional parameters
Logg::addErr("New error log"); //no additional parameters - uses filename and path from "Logg::$fileName" and "Logg::$filePath"
Logg::addErr("New error log in different file", "<file name>"); //one additional parameter - uses provided filename instead of "Logg::$fileName"
Logg::addErr("New error log in different file and path", '<file name>', '<file path>'); //two additional parameters - uses provided filename and path instead of "Logg::$fileName" and "Logg::$filePath"
例子:
//this:
{
//logging information to different file in different path
Logg::addInfo(['Some info', 15], 'AnotherFileName', '/some/different/path/');
}
//is equal to this:
{
//changing filename and path
Logg::$fileName = 'AnotherFileName';
Logg::$filePath = '/some/different/path/';
//logging information
Logg::addInfo(['Some info', 15]);
//changing filename and path back to its original values
Logg::$fileName = 'ExampleName_'.date("Y_m_d");
Logg::$filePath = 'C:/Apache24/htdocs/public_html/logs/';
}
一切都取决于您要记录什么。默认情况下,您已经拥有一个错误日志,它基本上是一个纯文本文件。如果您想记录代码中的事件以进行调试或跟踪脚本中的活动,则需要为此编写自己的日志处理程序,但这非常简单。正如另一个帖子所说,您可以使用error_log()函数将内容推送到错误日志中,但这会导致一些非常难以管理的日志文件。