在自定义记录器中 print_r()ing 变量时排除对象

发布于 2024-11-11 02:44:48 字数 3705 浏览 3 评论 0原文

我有记录器类,它正在记录所有内容。对象将使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

二智少女 2024-11-18 02:44:48

当对象被转换为字符串时,__toString() 被调用。您可以尝试使用is_object()之类的方法

$objectString = method_exists($object, '__toString')
              ? (string) $object
              : print_r($object, true);

来确定值是否是对象。

根本

$string = !is_object($value) || method_exists($value, '__toString')
        ? (string) $value
        : print_r($value, true);

__toString() is called, when the object is casted to a string. You may try something like

$objectString = method_exists($object, '__toString')
              ? (string) $object
              : print_r($object, true);

Use is_object() to find out, if a value is an object or not.

At all

$string = !is_object($value) || method_exists($value, '__toString')
        ? (string) $value
        : print_r($value, true);
書生途 2024-11-18 02:44:48

您可以使用自己的函数包装 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 use is_a() if you only want to exclude certain classes of objects.

戒ㄋ 2024-11-18 02:44:48

作为 html 解决方案,您可以使用:

<pre><?=print_r(log_content);?></pre>

更好地显示您的日志文件。我以这种方式显示日志文件。

as a html solution you can use:

<pre><?=print_r(log_content);?></pre>

to display your log file better. I am displaying the log files in this way.

土豪 2024-11-18 02:44:48
if (is_object( $foo ))
{
  print_r( $foo->__toString() );
} else {
  print_r( $foo );
}
if (is_object( $foo ))
{
  print_r( $foo->__toString() );
} else {
  print_r( $foo );
}
蓬勃野心 2024-11-18 02:44:48

如果您可以更改 Logger 类,则可以在打印之前检查该类:

if(!($var instanceof HeavyMVCObject)){
    print_r($var);
}

If you can alter the Logger class, you can check for the class befpre you print it:

if(!($var instanceof HeavyMVCObject)){
    print_r($var);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文