Exception: Serialization of 'Closure' is not allowed

匿名 (未验证) 提交于 2019-12-03 02:26:02

问题:

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:

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:

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.

回答1:

Apparently anonymous functions cannot be serialized.

Example

$function = function () {     return "ABC"; }; serialize($function); // would throw error

From your code you are using Closure

$callback = function () // 

Solution 1 : Replace with with a normal function Example

function emailCallback() {     return 'ZendMail_' . microtime(true) . '.tmp'; } $callback = "emailCallback" ;

Solution 2 : Indirect method call by array variable

If you look at 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'); setOptions($options);    79     }

You can use the same approach to send the callback

$callback = array($this,"aMethodInYourClass");


回答2:

Direct Closure serialisation is not allowed by PHP. But you can use powefull class like PHP Super Closure : https://github.com/jeremeamia/super_closure

This class is really simple to use and is bundled into the laravel framework for the queue manager.

From the github documentation :

$helloWorld = new SerializableClosure(function ($name = 'World') use ($greeting) {     echo "{$greeting}, {$name}!\n"; });  $serialized = serialize($helloWorld);


回答3:

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

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.



回答4:

You have to disable Globals

 /**  * @backupGlobals disabled  */


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!