문제

PNG 이미지를 즉시 생성하여 브라우저로 보낸 PHP 클래스가 있습니다. PHP 매뉴얼은 imageStroy 메모리를 해제하기 위해 끝에 기능이 호출됩니다. 이제 수업을 사용하지 않았다면 다음과 같은 코드가 있습니다.

function shutdown_func() 
{
    global $img;
    if ($img)
        imagedestroy($img);
}
register_shutdown_function("shutdown_func");

그러나 나는 수업에 적합한 장소가 imageStroy 클래스의 파괴자.

파괴자가 셧다운 기능이 같은 방식으로 호출되는지 알아 내지 못했습니까? 예를 들어, 사용자가 브라우저에서 정지 버튼을 누르면 실행이 중지되는 경우.

참고 : 답변에 쓰는 것은 무엇이든,이를 지원하는 기사 나 매뉴얼 페이지 (URL)를 가리 키십시오.

도움이 되었습니까?

해결책

방금 Apache, PHP가 Apache 모듈로 사용되는 테스트를 거쳤습니다. 나는 다음과 같은 끝없는 루프를 만들었습니다.

<?php
class X
{
    function __destruct()
    {
        $fp = fopen("/var/www/htdocs/dtor.txt", "w+");
        fputs($fp, "Destroyed\n");
        fclose($fp);
    }
};

$obj = new X();
while (true) {
    // do nothing
}
?>

내가 찾은 내용은 다음과 같습니다.

  • Firefox에서 정지 버튼을 누르면이 스크립트가 중지되지 않습니다.
  • Apache를 종료하면 Destructor가 전화하지 않습니다.
  • PHP에 도달하면 중지됩니다. max_execution_time이 호출되지 않습니다.

그러나 이렇게하는 것 :

<?php
function shutdown_func() {
    $fp = fopen("/var/www/htdocs/dtor.txt", "w+");
    fputs($fp, "Destroyed2\n");
    fclose($fp);
}
register_shutdown_function("shutdown_func");

while (true) {
    // do nothing
}
?>

shutdown_func가 호출됩니다. 따라서 이것은 클래스 데스헌터가 셧다운 기능만큼 좋지 않다는 것을 의미합니다.

다른 팁

당신이 해야하는 원칙에 따라 시작한 것을 끝내십시오, 나는 파괴자가 무료 전화를위한 올바른 장소라고 말하고 싶습니다.

그만큼 폐물 소각로 물체가 폐기 될 때 호출되는 반면 종료 기능 스크립트 실행이 완료 될 때까지 호출되지 않습니다. Wolfie가 언급했듯이 서버 나 스크립트를 강제로 중단하면 반드시 발생하지는 않지만 당시 PHP가 할당 한 메모리는 어쨌든 해제됩니다.

또한 Wolfie가 언급 한 PHP는 스크립트가 닫히면 스크립트 리소스를 확보 할 것입니다. 따라서 이러한 개체 중 하나만 인스턴스화한다면 아마도 큰 차이를 발견하지 못할 것입니다. 그러나 나중에 이런 것들을 인스턴스화하거나 루프에서 그렇게한다면, 메모리 사용이 갑자기 급증하는 것에 대해 걱정할 필요가 없을 것입니다. 원래 추천; 그것을 소멸자에 넣으십시오.

서버가 타임 아웃을 경험하는 경우에 대해 특별히 파괴를 처리하려고 노력하면서 최근에 문제가 발생했으며 오류 로그에 클래스 데이터를 포함시키고 싶었습니다. 참조 및 $이 this를 참조 할 때 오류를받을 것입니다 (몇 가지 예제, 아마도 버전 문제 또는 Symfony 부작용에서 수행 한 것을 보았지만), 내가 생각해 낸 솔루션은 상당히 깨끗했습니다.

class MyClass
{
    protected $myVar;

    /**
     * constructor, registers shutdown handling
     */
    public function __construct()
    {
        $this->myVar = array();

        // workaround: set $self because $this fails
        $self = $this;
        // register for error logging in case of timeout
        $shutdown = function () use (&$self) {
            $self->shutdown();
        };
        register_shutdown_function($shutdown);
    }

    /**
     * handle shutdown events
     */
    public function shutdown()
    {
        $error = error_get_last();
        // if shutdown in error
        if ($error['type'] === E_ERROR) {
            // write contents to error log
            error_log('MyClass->myVar on shutdown' . json_encode($this->myVar), 0);
        }
    }

    ...

이것이 누군가를 돕기를 바랍니다!

스크립트가 종료되면 스크립트 실행 중에 모든 메모리 PHP가 할당 된 모든 메모리 PHP가 할당 된 것입니다. 사용자가 스톱 버튼을 누르더라도 PHP는 스크립트가 완료 될 때까지 스크립트를 처리하고 HTTP 데몬에 다시 방문하여 방문자에게 제공됩니다 (또는 데몬이 얼마나 영리한 지에 따라).

따라서 스크립트 실행 종료시 메모리를 명시 적으로 풀어주는 것은 약간 중복됩니다. 어떤 사람들은 그것이 좋은 일이라고 주장 할 수도 있지만 여전히 중복됩니다.

그러나 클래스 소멸자의 주제에서, 그들은 대상이 파괴 될 때마다 호출됩니다. unset() 또는 스크립트 완료/종료시.

이미지 조작에 사용 된 메모리를 명시 적으로 풀어주는 개발자의 권장 사항은 비트 맵 (높이 * 너비 * 비트 깊이 * 3 (+ 1 알파 채널이있는 경우)))

위키 백과의 요구를 충족시키기 위해 :

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top