Исключение: Сериализация «Закрытие» не допускается

Поэтому я не совсем уверен, что мне нужно будет показать вам, ребята, как бы то ни было, если вам нужно больше кода, пожалуйста, не стесняйтесь спрашивать:

Таким образом, этот метод настроит initMailer для Zend в нашем приложении:

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; } 

Вы можете увидеть закрытие, которое находится внутри. Когда я запускаю какие-либо тесты, которые используют этот код, я получаю:

 Exception: Serialization of 'Closure' is not allowed 

и, следовательно, все тесты в связи с этим «закрытием» терпят неудачу. Поэтому я здесь прошу вас, ребята, что я должен делать.

Для выяснения вышеизложенного все делали это, говоря, что любое электронное письмо, которое мы отправляем, мы хотим хранить информацию об этом письме в папке / tmp / mail / directory в файле.

По-видимому, анонимные функции не могут быть сериализованы.

пример

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

Из вашего кода вы используете Closure

 $callback = function () // <---------------------- Issue { return 'ZendMail_' . microtime(true) . '.tmp'; }; 

Решение 1. Замените с нормальной функцией. Пример.

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

Решение 2. Косвенный вызов метода по переменной массива

Если вы посмотрите на 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 } 

Вы можете использовать тот же подход для отправки обратного вызова

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

PHP не допускает сериализации с прямым закрытием. Но вы можете использовать класс powefull, например PHP Super Closure: https://github.com/jeremeamia/super_closure

Этот класс очень прост в использовании и входит в структуру laravel для менеджера очередей.

Из документации github:

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

Как уже говорилось: закрытие, из коробки, не может быть сериализовано.

Однако, используя магические методы __sleep() , __wakeup() и отражение и CAN, вручную делают замыкания сериализуемыми. Подробнее см. Расширение-php-5-3-closures-with-serialization-and-reflection

Это использует отражение и функцию php eval . Обратите внимание, что это открывает возможность инъекции CODE, поэтому, пожалуйста, обратите внимание на то, что вы сериализуете.

Вы должны отключить глобальные

  /** * @backupGlobals disabled */