在自定义记录器中 print_r()ing 变量时排除对象
我有记录器类,它正在记录所有内容。对象将使用 print_r 记录为人类可读的状态。我的问题是我有一个大的 MVC 对象。每次发生异常或错误时,MVC-Object 也会通过 print_r 打印在日志中。这会导致日志文件非常非常长,阅读起来并不友好。
我尝试为我的 MVC 类设置一个 __toString() 方法,但这不起作用。我还在 Log 中获得了完整的 MVC 对象。 MVC 是一个单例,并且在每个对象上都被引用。因此,在对象进入 print_r 之前简单地将其排除并不是那么容易。
有没有办法从 print_r 中排除对象?
我的方法:
LOG-Class errorHandler-Method:
public static function errorHandler($errno, $errstr, $errfile, $errline, $vars) {
//If @ is set, don't do anything!
if(error_reporting() === 0) {
return;
}
//Get StackTrace with low memory usage ;)
$e = new Exception();
$stackStr = $e->getTraceAsString();
//Build ErrorMessage for Log
$message = 'File: '.$errfile.' - L: '.$errline."\n".
'Code: '.$errno."\n".
'Message: '.$errstr."\n".
'Vars: '.print_r($vars, true)."\n".
'Stacktrace: '.$stackStr;
self::error($message);
}
LOG-Class error-Method:
public static function exceptionHandler(Exception $e) {
$message = get_class($e).': '.$e->getMessage()."\n".
'File: '.$e->getFile().' - L: '.$e->getLine()."\n".
'Code: '.$e->getCode()."\n".
'Message: '.$e->getMessage()."\n".
'Stacktrace: '.$e->getTraceAsString();
self::error($message);
}
LOG-Class error-Method:
public static function error($data, $file='system.log') {
$config = Megaira_PropertyConfiguration::getInstance();
switch($config->get('LOG_MODE')) {
case'DEEPDEBUG':
case'ERROR':
case'WARNING':
case'INFO':
case'DEBUG':
self::writeToLog('ERROR', $data, $file);
break;
}
}
LOG-Class writeToLog-Method:
private static function writeToLog($mode='', $text='', $file=''){
if(!is_string($text) && !is_numeric($text)) {
$text = print_r($text, true);
}
$config = Megaira_PropertyConfiguration::getInstance();
if(!$config->get('LOGGINGACTIVE')) { return; }
self::writeLineToFile($mode, $text, $file);
}
设置错误和异常处理程序:
//Set Error and Exception Handler
set_error_handler(array(new LOG(), 'errorHandler'));
set_exception_handler(array(new LOG(), 'exceptionHandler'));
谢谢
一些测试:
public static function print_r_filtered($object, $ret=false) {
$filtered = array(
'Megaira_MVC'
);
$text = print_r($object, true);
foreach($filtered as $filter) {
$search = '#('.$filter.'\sObject)\n(\s+)\).*?\n\2\)\n#s';
$replace = "$1";
$text = preg_replace($search, $replace, $text);
}
if($ret)
return $text;
echo $text;
}
不起作用。也许正则表达式失败了?
解决方案:
这是一个设计缺陷。 errorHandler 正在记录发生错误的地方使用的所有对象。因此,在index.php 中有以下代码:
$mvc = Megaira_MVC::getInstance();
因此,这段代码通过 LOG-Class 中的 errorHandler 使用 print_r 生成了 Var $mvc
的日志记录。
我的结论是:不要在大型单例对象上使用变量,或者如果不再需要 Var,请使用 unset() 。
I have Logger-Class which is logging everything. Objects will be logged with print_r to a human-readable state. My Problem is that I have a big MVC-Object. Everytime an Exception or Error occurs, the MVC-Object will also be printed in the Log by print_r. This results in a very very long Logfile that is not really friendly to read.
I tried to set a __toString()
method to my MVC-Class but this don't work. I also get the complete MVC-Object in Log. The MVC is a Singleton and is referenced on every Object. So to simple exclude the Object before it cames into the print_r is not that easy.
Is there any way to exclude Objects from print_r?
My Methods:
LOG-Class errorHandler-Method:
public static function errorHandler($errno, $errstr, $errfile, $errline, $vars) {
//If @ is set, don't do anything!
if(error_reporting() === 0) {
return;
}
//Get StackTrace with low memory usage ;)
$e = new Exception();
$stackStr = $e->getTraceAsString();
//Build ErrorMessage for Log
$message = 'File: '.$errfile.' - L: '.$errline."\n".
'Code: '.$errno."\n".
'Message: '.$errstr."\n".
'Vars: '.print_r($vars, true)."\n".
'Stacktrace: '.$stackStr;
self::error($message);
}
LOG-Class exceptionHandler-Method:
public static function exceptionHandler(Exception $e) {
$message = get_class($e).': '.$e->getMessage()."\n".
'File: '.$e->getFile().' - L: '.$e->getLine()."\n".
'Code: '.$e->getCode()."\n".
'Message: '.$e->getMessage()."\n".
'Stacktrace: '.$e->getTraceAsString();
self::error($message);
}
LOG-Class error-Method:
public static function error($data, $file='system.log') {
$config = Megaira_PropertyConfiguration::getInstance();
switch($config->get('LOG_MODE')) {
case'DEEPDEBUG':
case'ERROR':
case'WARNING':
case'INFO':
case'DEBUG':
self::writeToLog('ERROR', $data, $file);
break;
}
}
LOG-Class writeToLog-Method:
private static function writeToLog($mode='', $text='', $file=''){
if(!is_string($text) && !is_numeric($text)) {
$text = print_r($text, true);
}
$config = Megaira_PropertyConfiguration::getInstance();
if(!$config->get('LOGGINGACTIVE')) { return; }
self::writeLineToFile($mode, $text, $file);
}
Setup the Error- and Exception-handler:
//Set Error and Exception Handler
set_error_handler(array(new LOG(), 'errorHandler'));
set_exception_handler(array(new LOG(), 'exceptionHandler'));
Thanks
Some Testing:
public static function print_r_filtered($object, $ret=false) {
$filtered = array(
'Megaira_MVC'
);
$text = print_r($object, true);
foreach($filtered as $filter) {
$search = '#('.$filter.'\sObject)\n(\s+)\).*?\n\2\)\n#s';
$replace = "$1";
$text = preg_replace($search, $replace, $text);
}
if($ret)
return $text;
echo $text;
}
Did not work. Maybe RegEx fail?
Solution:
It was a Design flaw. The errorHandler is Logging all Objects that are used on the place the error occurs. So in the index.php are the following code:
$mvc = Megaira_MVC::getInstance();
So this peace of code produced a logging of the Var $mvc
with print_r through the errorHandler in LOG-Class.
Conclusion for me: Don't use Variables on big Singleton-Objects or use unset() if the Var is not needed anymore.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
当对象被转换为字符串时,
__toString()
被调用。您可以尝试使用is_object()
之类的方法来确定值是否是对象。
根本
__toString()
is called, when the object is casted to a string. You may try something likeUse
is_object()
to find out, if a value is an object or not.At all
您可以使用自己的函数包装 print_r,使用
is_object()
函数检查提供的数据是否包含任何对象。同样,如果您只想排除某些对象类,则可以使用is_a()
。You could wrap print_r with your own function that checks whether the provided data includes any objects, using the
is_object()
function. Similarly, you could useis_a()
if you only want to exclude certain classes of objects.作为 html 解决方案,您可以使用:
更好地显示您的日志文件。我以这种方式显示日志文件。
as a html solution you can use:
to display your log file better. I am displaying the log files in this way.
如果您可以更改 Logger 类,则可以在打印之前检查该类:
If you can alter the Logger class, you can check for the class befpre you print it: