php-不允许序列化“关闭”

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

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.

我试图了解是什么导致“不允许关闭序列化”异常.

谢谢!

解决方法:

PHP’s backtrace structure包含对该对象的引用,该对象的方法在堆栈的每个级别上都被调用.当它尝试序列化跟踪时,任何引用闭包的对象(或本身引用闭包的引用对象等)都将阻止序列化.

在您的情况下,您可以将跟踪重新铸成描述性较小的形式,或者查找包含闭包的对象,然后将闭包重新包装为__invoke实例,或者在序列化时通过实现Serializable as described here跳过它们.在这里,您的选择取决于您的选择正在处理跟踪.如果只是为了让人们容易理解问题的发生,请考虑使用getTraceAsString()方法而不是getTrace().

上一篇:[源码解析] 消息队列 Kombu 之 基本架构


下一篇:[源码分析] 分布式任务队列 Celery 之 发送Task & AMQP