[英]Excluding objects when print_r()ing variables in a custom logger
我有记录所有内容的记录器类。 对象将使用 print_r 记录到人类可读的 state。 我的问题是我有一个很大的 MVC 对象。 每次发生异常或错误时,MVC-Object 也会被 print_r 打印在 Log 中。 这会导致日志文件非常长,阅读起来并不友好。
我试图为我的 MVC-Class 设置一个__toString()
方法,但这不起作用。 我还在 Log 中获得了完整的 MVC-Object。 MVC 是 Singleton 并在每个 Object 上引用。 因此,在 Object 进入 print_r 之前简单地排除它并不是那么容易。
有没有办法从 print_r 中排除对象?
我的方法:
LOG 类 errorHandler 方法:
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);
}
日志类错误方法:
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 类 writeToLog 方法:
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()。
__toString()
在 object 被转换为字符串时被调用。 你可以尝试类似
$objectString = method_exists($object, '__toString')
? (string) $object
: print_r($object, true);
使用is_object()
找出一个值是否为 object。
根本
$string = !is_object($value) || method_exists($value, '__toString')
? (string) $value
: print_r($value, true);
您可以使用您自己的 function 包装 print_r,使用is_object()
function 检查提供的数据是否包含任何对象。 同样,如果您只想排除某些类别的对象,则可以使用is_a()
。
作为 html 解决方案,您可以使用:
<pre><?=print_r(log_content);?></pre>
更好地显示您的日志文件。 我以这种方式显示日志文件。
if (is_object( $foo ))
{
print_r( $foo->__toString() );
} else {
print_r( $foo );
}
如果您可以更改记录器 class,您可以在打印之前检查 class:
if(!($var instanceof HeavyMVCObject)){
print_r($var);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.