php 例外:不允许序列化“Closure”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13734224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Exception: Serialization of 'Closure' is not allowed
提问by TheWebs
So I am not sure exactly what I would have to show you guys, how ever if you need more code please do not hesitate to ask:
所以我不确定我必须向你们展示什么,如果你需要更多代码,请不要犹豫,问:
So this method will set up the initMailer for Zend with in our application:
所以这个方法将在我们的应用程序中为 Zend 设置 initMailer:
protected function _initMailer()
{
if ('testing' !== APPLICATION_ENV) {
$this->bootstrap('Config');
$options = $this->getOptions();
$mail = new Zend_Application_Resource_Mail($options['mail']);
}elseif ('testing' === APPLICATION_ENV) {
//change the mail transport only if dev or test
if (APPLICATION_ENV <> 'production') {
$callback = function()
{
return 'ZendMail_' . microtime(true) .'.tmp';
};
$mail = new Zend_Mail_Transport_File(
array('path' => '/tmp/mail/',
'callback'=>$callback
)
);
Zend_Mail::setDefaultTransport($mail);
}
}
return $mail;
}
You can see the closure that lies with in. When I run any tests that use this code I get:
你可以看到 in 的闭包。当我运行任何使用此代码的测试时,我得到:
Exception: Serialization of 'Closure' is not allowed
and thus all the tests in relation to this "closure" fails. So I am here asking you guys what I should do.
因此所有与此“关闭”相关的测试都失败了。所以我在这里问你们我应该怎么做。
For clarification on the above, all were doing is saying that any email we send out we want to store information about that email in a folder in the /tmp/mail/ directory in a file.
为了澄清上述问题,我们所做的只是说我们发送的任何电子邮件都希望将有关该电子邮件的信息存储在 /tmp/mail/ 目录中的文件夹中的文件中。
采纳答案by Baba
Apparently anonymous functions cannot be serialized.
显然匿名函数不能被序列化。
Example
例子
$function = function () {
return "ABC";
};
serialize($function); // would throw error
From your code you are using Closure:
从您的代码中,您正在使用 Closure:
$callback = function () // <---------------------- Issue
{
return 'ZendMail_' . microtime(true) . '.tmp';
};
Solution 1 :Replace with a normal function
解决方案1:替换为正常功能
Example
例子
function emailCallback() {
return 'ZendMail_' . microtime(true) . '.tmp';
}
$callback = "emailCallback" ;
Solution 2 :Indirect method call by array variable
解决方案 2:通过数组变量间接调用方法
If you look at http://docs.mnkras.com/libraries_23rdparty_2_zend_2_mail_2_transport_2file_8php_source.html
如果您查看 http://docs.mnkras.com/libraries_23rdparty_2_zend_2_mail_2_transport_2file_8php_source.html
public function __construct($options = null)
63 {
64 if ($options instanceof Zend_Config) {
65 $options = $options->toArray();
66 } elseif (!is_array($options)) {
67 $options = array();
68 }
69
70 // Making sure we have some defaults to work with
71 if (!isset($options['path'])) {
72 $options['path'] = sys_get_temp_dir();
73 }
74 if (!isset($options['callback'])) {
75 $options['callback'] = array($this, 'defaultCallback'); <- here
76 }
77
78 $this->setOptions($options);
79 }
You can use the same approach to send the callback
您可以使用相同的方法发送回调
$callback = array($this,"aMethodInYourClass");
回答by Ifnot
Direct Closure serialisation is not allowed by PHP. But you can use powefull class like PHP Super Closure : https://github.com/jeremeamia/super_closure
PHP 不允许直接关闭序列化。但是你可以使用像 PHP Super Closure 这样的 powefull 类:https: //github.com/jeremeamia/super_closure
This class is really simple to use and is bundled into the laravel framework for the queue manager.
这个类使用起来非常简单,并且被捆绑到队列管理器的 Laravel 框架中。
From the github documentation :
从 github 文档:
$helloWorld = new SerializableClosure(function ($name = 'World') use ($greeting) {
echo "{$greeting}, {$name}!\n";
});
$serialized = serialize($helloWorld);
回答by ArjanW
As already stated: closures, out of the box, cannot be serialized.
如前所述:开箱即用的封盖无法序列化。
However, using the __sleep(), __wakeup()magic methods and reflection u CAN manually make closures serializable. For more details see extending-php-5-3-closures-with-serialization-and-reflection
但是,使用__sleep(),__wakeup()神奇的方法和反思U可以手动进行关闭序列化。有关更多详细信息,请参阅extends-php-5-3-closures-with-serialization-and-reflection
This makes use of reflection and the php function eval. Do note this opens up the possibility of CODE injection, so please take notice of WHAT you are serializing.
这利用了反射和 php 函数eval。请注意,这可能会导致 CODE 注入,因此请注意您正在序列化的内容。
回答by Sampath Perera
You have to disable Globals
你必须禁用全局
/**
* @backupGlobals disabled
*/

