【问题标题】:Serialization of 'Closure' is not allowed不允许序列化“闭包”
【发布时间】:2014-04-21 11:22:28
【问题描述】:

我的代码中有一个自定义异常处理程序(以前可以正常工作),直到昨天我突然看到这个错误:

PHP Fatal error:  Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed' in /raid0/nginx/www/voiceportal/lib/logutils.php:34 Stack trace:
#0 /raid0/nginx/www/voiceportal/lib/logutils.php(34): serialize(Array)
#1 [internal function]: custom_exception_handler(Object(AMQPConnectionException))
#2 {main}

我读到如果尝试序列化匿名函数可能会导致这种情况,但这就是我抛出错误的原因:

//logutils.php
function custom_exception_handler($exception) {
   $trace_id = uniqid();
   $trace = serialize(array('trace_id' => $trace_id, 'trace' => $exception->getTrace()));
   ...
}

不确定是否是由于尝试序列化 getTrace() 引起的,但如果我没记错的话,它以前可以工作。

最初的异常是(如跟踪所示)AMQPConnectionException

我正在尝试了解导致 'Serialization of Closure not allowed' 异常的原因。

谢谢!

【问题讨论】:

  • $exception->getTrace() 的返回值是什么?
  • 不知道主代码发生了什么异常,所以不知道。
  • 我不明白你的问题。您必须提供更多详细信息
  • 原来的异常是 AMQPConnectionException。问题中添加了更多详细信息。
  • 您必须显示custom_exception_handler 的完整正文以及捕获此异常的代码

标签: php exception closures amqp


【解决方案1】:

PHP's backtrace structure 包含对在堆栈的每一级调用其方法的对象的引用。当它尝试序列化跟踪时,任何引用闭包的对象(或本身引用闭包的引用对象等)都将阻止序列化。

在您的情况下,您可以将跟踪重新转换为描述性稍差的形式,或者查找哪些对象包含闭包,然后将闭包重新打包为 __invoke 实例,或者在序列化时通过实现 Serializableas described here 跳过它们.您在此处的选择取决于您对跟踪所做的工作。如果它只是为了对错误进行人类可读的描述,请考虑使用getTraceAsString() 方法而不是getTrace()

【讨论】:

    【解决方案2】:

    我编写了一个函数,允许对任何Exception 进行序列化。这是通过展平回溯中的复杂值来完成的。

    来源:

    https://gist.github.com/Thinkscape/805ba8b91cdce6bcaf7c

    用法:

    //logutils.php
    function custom_exception_handler($exception) {
       flattenExceptionBacktrace($exception); // <---- ADD THIS
       $trace_id = uniqid();
       $trace = serialize(array('trace_id' => $trace_id, 'trace' => $exception->getTrace()));
       ...
    }
    

    【讨论】:

      【解决方案3】:

      我知道这是个老话题,但我想推荐我自己的library to serializing stack traces。对象 $stackTrace 可以包含值并且可以序列化。未序列化的对象将仅包含变量的自定义转储 (@see interface)。

      【讨论】:

        猜你喜欢
        • 2017-02-14
        • 2014-06-20
        • 1970-01-01
        • 1970-01-01
        • 2020-04-06
        • 2012-11-23
        • 2018-05-08
        • 1970-01-01
        • 2019-01-30
        相关资源
        最近更新 更多