2

PHPでこのエラーが発生する最も一般的な理由を誰かに教えてもらえますか?

でアクティブなラムダ関数を破棄できません...

どこかに、それ自体への参照を含むクロージャを破棄しようとしているコードがあり、コンパイラはこれに悩まされていると思います。

これらは私が望むよりも定期的に取得しており、どのパターンを使用しているのか、それが原因である可能性が高いのではないかと思います。

コードスニペットを添付しますが、エラーは通常、ヒントを提供する可能性のあるファイル内の行ではなく、ファイルを指します。

4

3 に答える 3

1

このような致命的なエラーは、次のようなコードになります。

set_exception_handler(function ($e) {
        echo "My exception handler";

        restore_exception_handler();

        throw new Exception("Throw this instead.");
});
throw new Exception("An exception");

またはこのように:

function destroy_handler() {
    restore_exception_handler();
}

function update_handler() {
    destroy_handler();
}

set_exception_handler(function ($e) {
        echo "My exception handler";

        update_handler();

        throw new Exception("Throw this instead.");
});
throw new Exception("An exception");

例外がスローされると、指定されたコールバックset_exception_handler()が実行され、 が呼び出されるとすぐに、restore_exception_handler()そのクロージャーへの同じ参照が独自​​のスコープ内で破棄 (または再割り当て) されるため、致命的なエラーが発生します (in の例でも同じことが言えます) hanskrentel at yahoo dot de。によって投稿されたリンクSameer K)。

2 番目の例から、スコープがネストされていても同じことが起こることがわかります。これは、restore_exception_handlerが最後に設定された例外ハンドラを破棄するためであり、そのコピーではありません (変数に初期値を与える式をまだ評価している間に、変数を再割り当てしたり、設定を解除したりするようなものです)。

コードのエラーが別のファイルを指していると言った場合は、他のファイルの関数やメソッドで実行が「ジャンプ」するラムダのすべての呼び出しを確認し、参照を再割り当てまたは破棄しているかどうかを確認することをお勧めしますラムダ自体。

于 2015-02-19T10:31:26.610 に答える
1

同じことに関してphp.netに投稿された同様のバグがあります。以下はリンクです。

お役に立てば幸いです。

https://bugs.php.net/bug.php?id=62452

于 2013-01-19T06:56:59.600 に答える
0

set_exception_handler前の例外ハンドラを返します:

以前に定義された例外ハンドラの名前を返します。エラーの場合は NULL を返します。以前のハンドラーが定義されていない場合は、NULL も返されます。 php.net: set_exception_handler

<?php

class MyException extends Exception {}

set_exception_handler(function(Exception $e){
    echo "Old handler:".$e->getMessage();
});

$lastHandler = set_exception_handler(function(Exception $e) use (&$lastHandler) {
    if ($e instanceof MyException) {
        echo "New handler:".$e->getMessage();
        return;
    }

    if (is_callable($lastHandler)) {
        return call_user_func_array($lastHandler, [$e]);
    }

    throw $e;
});

例外ハンドラーをトリガーします。

throw new MyException("Exception one", 1);

出力:New handler:Exception one

throw new Exception("Exception two", 1);

出力:Old handler:Exception two

于 2015-12-09T14:50:46.783 に答える