可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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 */