>백엔드 개발 >PHP 튜토리얼 >php_php 스킬의 __destruct 및 Register_shutdown_function 실행 순서

php_php 스킬의 __destruct 및 Register_shutdown_function 실행 순서

WBOY
WBOY원래의
2016-05-16 20:34:431043검색

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을 등록하고 모든 동작을 함수에 넣는 것이 가장 좋습니다.
제 말을 정정해주세요.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.