0

私は非常に興味深い問題を抱えています。私にとって良い解決策を持っている人がいるかどうか疑問に思います:

考えられるすべてのエラーをログ ファイルに記録しています。例外、致命的なエラー、警告、通知、JS エラー (Ajax 経由で送信) などを含む...

ここで、デバッグの目的で、これらすべてのエラーを HTML ページにも表示したいと思いました (そのため、ログ ファイルを確認する必要はありません)。

このため、すべての新しいエラーをセッション変数内に保存しています。ユーザーがそれを見たとき、それはセッションから削除されています。

私の問題:

エラー/例外の php-backtrace には多くの情報が含まれています。$_SESSION のようなグローバル変数を含みます。

また、すべての情報をセッションに保存するため、エラーが発生するたびにセッション サイズが 2 倍になります。(セッション内の各エラー メッセージには、このエラーが発生する前のセッションの内容全体が含まれます)

例えば:

エラーなし:

$_SESSION = array();

最初のエラー:

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

2 番目のエラー:

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

(これは単純化された例です)

エラーが 5 回発生した後、セッションはすでに大きすぎて、ローカル サーバーからロードできなくなりました (タイムアウト)。

5 または sth の深さの後に、配列からすべての要素を切り取ることを考えました。そのように。または、php がグローバル変数をバックトレースに保存しないようにすることは可能ですか?

現時点では、トレースをセッションに保存していませんが、基本的なトレース情報を引き続き表示できるより良い解決策を誰かが知っている可能性があります

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 に答える