2017-01-18 17 views
1

나는 여러개의 answers on object destruction order을 보았고, 모든 순서가 보장되지 않는다는 것을 지적했습니다. 이후 주문을 제어 할 수 없습니다, 나는 모든 개체가 파괴 된 후 함수를 호출하고 싶습니다.모든 객체가 파손 된 후 PHP 함수 호출

register_shutdown_function은 개체 삭제 전에 호출되므로 옵션이 아닙니다. 내가 "늦게"호출되는 개체를 사용하여 set_error_handler 같은 트릭을 보았지만 충분하지 않습니다.

문제의 배경은 경로 (보기) 레이어에 대해 수십 개의 개별 파일이있는 complex CMS입니다. 일반적인 부트 인클루드가 있지만 종료시에 실행되는 일반적인 부트 인클루드는 없습니다. 공통된 상속 된 기본 클래스를 통해 APCu 객체 캐싱을 사용하고 있으며 객체가 제거되었는지 확인해야합니다. 페이지로드 중에 작성된 동일한 오브젝트의 임의의 두 인스턴스에 대해 하나는 자체를 제거하고 다른 하나는 자체 캐시하려고 할 수 있습니다. 분명히 다른 모든 것들을 제거해야하므로, 전역 캐시 키 세트에서 apc_delete를 호출하여 모든 __destruct() 이온을 제거해야합니다.

+1

흥미로운 문제. "페이지로드 중에 생성 된 동일한 객체의 두 인스턴스에 대해 하나는 자체를 제거하고 다른 하나는 자체적으로 캐시하려고 할 수 있습니다"라는 것이 설계상의 결함 인 것 같습니다. 당신은 항상 객체의 모든 인스턴스가 최신 인스턴스가되기를 원하지 않습니까? 귀하의 캐싱/로딩 레이어가 이것을 처리 할 것이라고 생각합니다. (나는 bitweaver에 관해서는 특별히 알지 못합니다.) –

+1

안녕 Matt, 디자인 결함 주석이 나를 생각하게했다. 당신은 정확합니다, 그리고 지금은 캐시에 객체를 저장하기 전에 제거 된리스트를 검사 할 것입니다. 더 적절한 해결책이지만, 가능한 경우 PHP에서 마지막 "마지막 호출"함수를 실행하는 방법을 알고 싶습니다. – Stickley

답변

3

위의 내 의견에서 말했듯이 여러 객체 인스턴스가 혼합 된 상태는 디자인 결함과 유사합니다. 난 항상 당신이 개체의 모든 인스턴스를 최신 것으로 생각하거나 적어도 그렇지 않은 경우 캐시를 만지지 말아야한다고 생각합니다. 나는 당신의 캐싱 및/또는 객체 로딩 레이어가 이것을 처리 할 수 ​​있다고 생각합니다.


이 근본적인 질문에 대답하기 위해, 나는 a script to test PHP's shutdown sequence을 썼다 :

<?php /* Adapted from https://evertpot.com/160/ */ 

    ob_start(
     function($buffer) { 
      return $buffer . "output buffer flushed\n"; 
     } 
    ); 

    $empty = function() { 
     return true; 
    }; 

    $close = function() { 
     echo "session close\n"; 
     return true; 
    }; 

    $write = function() { 
     echo "session write\n"; 
     return true; 
    }; 

    session_set_save_handler($empty, $close, $empty, $write, $empty, $empty); 
    session_start(); 

    register_shutdown_function(
     function() { 
      echo "register_shutdown_function\n"; 
     } 
    ); 

    class MyClass { 
     function __destruct() { 
      echo "object destructor\n"; 
     } 
    } 
    $myObject = new MyClass; 

출력 :

register_shutdown_function 
object destructor 
output buffer flushed 
session write 
session close 

그것은 가까운 출력 버퍼링 및 세션 쓰기 /의 높이가 2 곳 곳이 있습니다 보인다 당신은 당신의 모든 물건이 파괴되었다는 것을 알고 있습니다. (이것은 또한 셧다운 함수로 등록 할 수있는 새로운 형태의 session_set_save_handler를 사용하지 않는다고 가정합니다.)

+0

대단하군요. session_close 핸들러는 완벽합니다. – Stickley

0

__destruct() 함수에서 함수를 호출하려고 했습니까? PHP는 모든 객체를 파괴 한 후에이 함수를 호출하므로 도움이 될 수 있습니다.