예외:'닫힘'을(를) 직렬화할 수 없습니다.
그래서 정확히 무엇을 보여드려야 할지 잘 모르겠습니다만, 코드가 더 필요하시면 주저하지 마시고 질문해 주시기 바랍니다.
따라서 이 방법을 사용하면 응용 프로그램 내에서 initMailer for 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/ 디렉토리의 폴더에 파일로 저장하기를 원한다는 것뿐이었습니다.
익명 기능을 직렬화할 수 없습니다.
예
$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에서는 직접 폐쇄 직렬화가 허용되지 않습니다.그러나 PHP Super Closure : https://github.com/jeremeamia/super_closure 같은 강력한 클래스를 사용할 수 있습니다.
이 클래스는 사용이 매우 간단하며 큐 관리자를 위한 래라벨 프레임워크에 번들로 제공됩니다.
github 문서에서:
$helloWorld = new SerializableClosure(function ($name = 'World') use ($greeting) {
echo "{$greeting}, {$name}!\n";
});
$serialized = serialize($helloWorld);
이미 기술된 바와 같이, 박스 밖의 폐쇄는 직렬화할 수 없습니다.
하지만 사용하는 것은.__sleep()
,__wakeup()
마법 방법과 반사를 통해 수동으로 닫힘을 직렬화할 수 있습니다.자세한 내용은 확장-php-5-3-closures-serialization-및 reflection을 참조하십시오.
이것은 reflection과 php function eval을 사용합니다.이것은 코드 주입의 가능성을 열어주는 것이므로, 당신이 연재하고 있는 것에 유의하시기 바랍니다.
Globals를 비활성화해야 합니다.
/**
* @backupGlobals disabled
*/
안전하지는 않지만 실험적입니다. 비활성화될 수 있는 evalu()를 사용해야 하는 것과 같은 여러 가지 위험이 있습니다.가장 좋은 것은 hedoc 예제에서 당신의 스크립트를 serialized에 쓰는 것일 것입니다.
$code = <<<CODE
<?php
class \$gen_class_{$user}{
...
}
CODE;
코드를 직렬화하거나 확장자 '.class.php'로 작성하여 코드를 보다 쉽게 사용할 수 있습니다. 스크립트를 쉽게 호출하여 영구적으로 만들 수 있습니다.
https://3v4l.org/jpHm9 업데이트 PHP 8
<?php
function closure_to_str($func)
{
$refl = new \ReflectionFunction($func); // get reflection object
$path = $refl->getFileName(); // absolute path of php file
$begn = $refl->getStartLine(); // have to `-1` for array index
$endn = $refl->getEndLine();
$dlim = PHP_EOL;
$list = explode($dlim, file_get_contents($path)); // lines of php-file source
$list = array_slice($list, ($begn-1), ($endn-($begn-1))); // lines of closure definition
$last = (count($list)-1); // last line number
if((substr_count($list[0],'function')>1)|| (substr_count($list[0],'{')>1) || (substr_count($list[$last],'}')>1))
{ throw new \Exception("Too complex context definition in: `$path`. Check lines: $begn & $endn."); }
$list[0] = ('function'.explode('function',$list[0])[1]);
$list[$last] = (explode('}',$list[$last])[0].'}');
return implode($dlim,$list);
}
$test = 10;
$dog2 = function($var=0) use ($test){
$var = 10;
echo $var . PHP_EOL;
return $test . $var;
};
echo closure_to_str($dog2)."\n\n";
반환 문자열
function($var=0) use ($test){
$var = 10;
echo $var . PHP_EOL;
return $test . $var;
}
언급URL : https://stackoverflow.com/questions/13734224/exception-serialization-of-closure-is-not-allowed
'source' 카테고리의 다른 글
glibc의 fclose(NULL)이 오류를 반환하지 않고 세그먼트화 오류를 발생시키는 이유는 무엇입니까? (0) | 2023.10.14 |
---|---|
검색 옵션을 사용하여 선택 상자 만들기 (0) | 2023.10.14 |
반복 합계에 우커머스 구독 사용자 지정 수수료 추가 (0) | 2023.10.14 |
운영 중인 도커 컨테이너의 확장 방법 (0) | 2023.10.14 |
C++ 네임스페이스 안에 외부 "C" 링크가 있습니까? (0) | 2023.10.14 |