0

我有一个非常有趣的问题,我想知道是否有人对我有很好的解决方案:

我在日志文件中记录了所有可能的错误。包括异常、致命错误、警告、通知、JS 错误(通过 Ajax 发送)、...

现在,出于调试目的,我也想在 HTML 页面上显示所有这些错误(所以我不需要检查日志文件)。

出于这个原因,我将每个新错误都存储在 Session-Variable 中。当用户看到它时,它就会从会话中删除。

我的问题:

错误/异常的 php-backtrace 包含大量信息。包括像 $_SESSION 这样的全局变量。

而且由于我将所有信息都存储在会话中,因此每次错误后会话大小都会翻倍。(会话中的每个错误消息都包含此错误之前会话的全部内容)

例如:

没有错误:

$_SESSION = array();

第一个错误:

$_SESSION = array(error1=>array("msg"="foo", session=array()));

第二个错误:

$_SESSION = array(error1=>array("msg"="foo", session=array()), error2 => array("msg"="foo2", session = array(error1=>array("msg"="foo", session=array()))));

(这只是一个简化的例子)

在 5 次错误之后,会话已经很大,我无法再从本地服务器加载它(超时)。

我考虑过在 5 或某个深度之后从数组中切割每个元素。像那样。或者是否可以防止php在回溯中存储全局变量?

目前,我没有将跟踪存储在 Session 中,但也许有人知道更好的解决方案,在那里我仍然可以看到基本的跟踪信息

4

1 回答 1

1

如果我能正确理解你,你想要做的是拥有某种每会话错误日志,稍后可以阅读。

我的建议是为每个会话创建单独的日志文件,您可以使用每个会话唯一的会话 ID 来识别日志文件。

<?php
define('PER_SESSION_LOG_PATH', '/tmp/logs/'); //or whatever path
/* return log handle */

class SessionLogger {

    static $fh;

    static function log_path() {
        return PER_SESSION_LOG_PATH . session_id() . '.log';
    }

    static function log_open() {
        if (!self::$fh) {
            self::$fh = fopen(self::log_path(), 'a+');
        }
        return self::$fh;
    }

    static function add_log($errors) {
        if (self::log_open()) {
            fwrite(self::$fh, serialize($errors) . PHP_EOL);
        }
    }

    static function log_close() {
        if (self::$fh) {
            fclose(self::$fh);
        }
    }

    //note that if the size of the log file is larger than memory_limit, you
    //may run into problems.
    //returns all the logs
    static function get_logs($truncate = TRUE) {
        $logs = array();
        if (self::log_open()) {
            while (!feof(self::$fh)) {
                $logs[] = unserialize(fgets(self::$fh));
            }
            //if the logs should be clear, then...
            if ($truncate) {
                fclose(self::$fh); //close and nullify handle 
                self::$fh = null;
                unlink(self::log_path()); //then delete log file.
            }
        }
        return $logs;
    }

}

然后你可以通过做添加错误

SessionLogger::add_log($error);

您还可以通过执行阅读日志

SessionLogger::get_logs(true); //or false if you don't want to delete file.
于 2013-07-06T14:33:38.287 回答