PHP 매뉴얼 분석에 따르면.
__destruct는
입니다.
소멸자는 객체에 대한 모든 참조가 삭제되거나 객체가 명시적으로 소멸될 때 실행됩니다.
및 register_shutdown_function은
입니다.
스크립트 실행이 완료되거나 exit()가 호출된 후 실행할 콜백을 등록합니다.
말 그대로 이해하면 __destruct는 개체 수준에 있고, Register_shutdown_function은 전체 스크립트 수준에 있습니다. Register_shutdown_function은 더 높은 수준에 있어야 하며, 등록된 함수도 마지막에 실행되어야 합니다. 추측을 확인하기 위해 다음 스크립트를 작성합니다.
Register_shutdown_function(function(){echo 'global';});
클래스 A {
공개 함수 __construct(){
}
공개 함수 __destruct()
{
echo __class__,'::',__function__,'
';
}
}
새로운 A;
실행 결과:
답변::__destruct
글로벌
우리의 추측이 완전히 확인되었으며, object->script 순서로 실행되었습니다.
하지만 객체에 Register_shutdown_function을 등록하면 어떻게 될까요? 아직도 같은 순서인가요? !
클래스 A {
공개 함수 __construct(){
Register_shutdown_function(function(){echo 'local', '
';});
}
공개 함수 __destruct()
{
echo __class__,'::',__function__,'
';
}
}
새로운 A;
결과:
현지
답변::__destruct
register_shutdown_function이 먼저 호출되고 마지막으로 실행 개체의 __destruct가 호출되는 것을 볼 수 있습니다. 이것은 Register_shutdown_function에 의해 등록된 함수가 클래스 내에서 메소드로 처리된다는 것을 나타냅니다. ! 잘 모르겠습니다. 구문 분석을 위해 PHP 소스 코드를 확인해야 할 수도 있습니다.
상황을 확인하기 위해 범위를 확장할 수 있습니다.
Register_shutdown_function(function(){echo 'global', '
';});
클래스 A {
공개 함수 __construct(){
Register_shutdown_function(array($this, 'op'));
}
공개 함수 __destruct()
{
echo __class__,'::',__function__,'
';
}
공개 함수 op()
{
echo __class__,'::',__function__,'
';
}
}
B급 {
공개 함수 __construct()
{
Register_shutdown_function(array($this, 'op'));
$obj = 새로운 A;
}
공개 함수 __destruct()
{
echo __class__,'::',__function__,'
';
}
공개 함수 op()
{
echo __class__,'::',__function__,'
';
}
}
$b = 새로운 B;
글로벌
B::op
답::op
답변::__destruct
B::__destruct
结果完全颠覆了我们的想就,register_shutdown_function函数无论类中注册还是에서전체局注册,它是先被执行,类中执行顺序就是它们被注册的先后顺序。如果我们再仔细研究,전체局的register_shutdown_function函数无论放이 前前side还是后면도시是这个结果,事情似乎有了结果,那就是register_shutdown_function比__destruct先执行,전체局적register_shutdown_function函数又先于类中注册的register_shutdown_function先执行。
且慢,我无法接受这个结果, 按光这样的结论, 难道说脚本已经结束后还可以再执行__destruct?!因此,我还要继续验证这个结论---去掉类中注册register_shutdown_function,而保留전체局register_shutdown_function:
클래스 A {
공개 함수 __destruct()
{
echo __class__,'::',__function__,'
';
}
}
B급 {
공개 함수 __construct()
{
$obj = 새로운 A;
}
공개 함수 __destruct()
{
echo __class__,'::',__function__,'
';
}
}
Register_shutdown_function(function(){echo 'global', '
';});
출처:
复主代码 代码如下:
답변::__destruct
글로벌
B::__destruct
결과는 혼란스럽습니다. 클래스 A와 B의 소멸자의 실행 순서에 대해서는 의심의 여지가 없습니다. A가 B에서 호출되기 때문에 클래스 A가 B보다 먼저 소멸되어야 하는데 어떻게 글로벌 Register_shutdown_function 함수를 그 사이에 끼울 수 있습니까? 처형될까? ! 수수께끼.
매뉴얼 분석에 따르면 소멸자는 종료 호출 시에도 실행될 수 있습니다.
exit()를 사용하여 스크립트를 종료하는 경우에도 소멸자는 호출됩니다. 소멸자에서 exit()를 호출하면 나머지 종료 작업이 중단됩니다.
exit가 함수에서 호출되는 경우 어떻게 호출되나요?
클래스 A {
공개 함수 __construct(){
register_shutdown_function(array($this, 'op'));
나가세요;
}
공개 함수 __destruct()
{
echo __class__,'::',__function__,'
';
}
공개 함수 op()
{
echo __class__,'::',__function__,'
';
}
}
B급 {
공개 함수 __construct()
{
register_shutdown_function(array($this, 'op'));
$obj = 새 A;
}
공개 함수 __destruct()
{
echo __class__,'::',__function__,'
';
}
공개 함수 op()
{
echo __class__,'::',__function__,'
';
}
}
Register_shutdown_function(function(){echo 'global', '
';});
$b = 새로운 B;
출력:
글로벌
B::op
답::op
B::__destruct
답변::__destruct
이 시퀀스는 위의 세 번째 예와 유사합니다. 클래스 B의 소멸자가 클래스 A보다 먼저 실행된다는 점이 다릅니다. 클래스 A에 대한 모든 참조는 B가 소멸된 후에만 소멸된다는 것이 사실인가요? ! 알려지지 않은.
결론:
1. 스크립트에서 Register_shutdown_function과 __destruct를 혼합하지 마십시오. 이들의 동작은 완전히 예측할 수 없습니다.
1. 객체는 서로 참조하기 때문에 객체가 언제 소멸될지 알 수 없습니다. 내용을 순서대로 출력해야 하는 경우 해당 내용을 소멸자 __destruct에 배치하면 안 됩니다.
2. 클래스에 Register_shutdown_function을 등록하지 마세요. 순서를 예측하기 어렵고(함수는 이 객체가 호출될 때만 등록됩니다) __destruct는 Register_shutdown_function을 완전히 대체할 수 있습니다.
3. 스크립트 종료 시 관련 동작을 수행해야 하는 경우에는 스크립트 시작 부분에 Register_shutdown_function을 등록하고 모든 동작을 함수에 넣는 것이 가장 좋습니다.
제 말을 정정해주세요.