prosource

PHP 디스트럭터

probook 2023. 8. 16. 22:28
반응형

PHP 디스트럭터

수업에서 __destruct를 사용해야 했던 실제 사례를 몇 가지 알려주세요.

알겠습니다, 제 마지막 답변이 적중하지 않은 것 같으니 다시 한번 해보겠습니다.이 주제에 대한 많은 자료와 사례가 인터넷에 있습니다.다른 프레임워크의 코드를 검색하고 검색하면 좋은 예를 볼 수 있습니다.

PHP가 종료 시 리소스를 닫는다고 해서 리소스가 더 이상 필요하지 않을 때(또는 닫지 않을 때) 명시적으로 닫는 것이 나쁜 것은 아니라는 것을 잊지 마십시오.사용 사례에 따라 다릅니다(끝까지 사용할 수 있는지, 아니면 한 번의 통화가 조기에 이루어졌다가 나머지 실행 기간 동안 다시 필요하지 않은지).

이제, 우리는 알고 있습니다.__destruct개체가 파괴될 때 호출됩니다.논리적으로, 물체가 파괴되면 어떻게 됩니까?음, 그것은 더 이상 사용할 수 없다는 것을 의미합니다.따라서 리소스가 열려 있다면, 리소스가 파괴될 때 리소스를 닫아야 하는 것이 타당하지 않습니까?물론, 일반적인 웹 페이지에서는 페이지가 곧 종료되므로 PHP가 이를 닫도록 하는 것은 보통 나쁘지 않습니다.그러나 어떤 이유로 스크립트가 오래 실행되면 어떻게 됩니까?그러면 자원 유출이 발생합니다.그렇다면 더 이상 필요하지 않을 때(또는 더 이상 사용할 수 없을 때) 모든 것을 닫지 않는 이유는 무엇입니까?

다음은 실제 프레임워크의 몇 가지 예입니다.

  1. 리튬의 리튬\net\소켓 클래스
  2. 코하나의 메모캐시 드라이버
  3. Zoomla의 FTP
  4. Zend Frameworks의 SMTP 메일 전송 클래스
  5. 코드 점화기의 T 템플릿 클래스
  6. 케이크를 위한 깔끔한 필터 도우미
  7. Symfony 세션 클래스에 소멸자 사용에 대한 Google 그룹 스레드

흥미로운 점은 코하나가 태그를 추적하여 나중에 캐시를 지우는 대신 "이름 공간"으로 삭제할 수 있다는 것입니다.따라서 파괴자를 사용하여 하드 스토리지에 대한 변경 사항을 플러시합니다.

또한 CodeIgniter 클래스는 디스트럭터의 출력 스트림에 디버깅 출력을 추가한다는 점에서 흥미로운 작업을 수행합니다.이것이 좋다고 말하는 것은 아니지만, 이것은 또 다른 용도의 예입니다.

마스터 컨트롤러에서 프로세스를 오래 실행할 때마다 개인적으로 소멸기를 사용합니다.시공자에서, 나는 다음을 확인합니다.pid파일. 해당 파일이 존재하고 해당 프로세스가 계속 실행 중이면 예외를 발생시킵니다.그렇지 않으면 현재 프로세스 ID로 파일을 만듭니다.그런 다음 디스트럭터에서 해당 파일을 제거합니다.자원을 해방하는 것보다 스스로를 정리하는 것이 더 중요합니다.

HTML 페이지를 생성하는 또 다른 유용한 사용법이 있습니다.

class HTMLgenerator {
  function __construct() {
    echo "<html><body>";
  }
  function __destruct() {
    echo "</body></html>";
  }
}

이 수업으로 당신은 글을 쓸 수 있습니다.

$html = new HTMLgenerator();
echo "Hello, world!";

그리고 그 결과는

<html><body>Hello, world!</body></html>

예:

<?php
class Session
{
    protected $data = array();

    public function __construct()
    {
        // load session data from database or file
    }

    // get and set functions

    public function __destruct()
    {
        // store session data in database or file
    }
};

이것이 파괴를 사용하는 좋은 이유입니다.세션 원본에 대한 읽기 및 쓰기를 항상 금지하고 시작과 끝에만 이 작업을 수행합니다.

나는 영화 정보 jpg 파일을 생성할 php 페이지를 만듭니다.이 페이지는 jpg로 변환하기 전에 템플릿(svg 파일)을 png으로 변환하기 위해 몇 가지 정보를 수집하고 잉크스케이프를 실행해야 합니다.svg에는 파일이어야 하는 다른 이미지에 대한 상대 링크가 포함되어 있습니다.그래서 내 페이지는 필요한 파일을 임시 폴더로 다운로드하고, svg 파일을 변환합니다.마지막으로 임시 폴더를 삭제해야 합니다.

나는 임시 폴더 삭제를 소멸자에 넣었습니다.페이지가 예기치 않게 끝나는 이유가 많아지기 전에 페이지가 종료되고 내가 확신할 수 있는 유일한 생각은 페이지가 종료될 때 소멸자가 호출된다는 것입니다.

이게 도움이 되길 바랍니다.

소멸기는 사용자 정의 데이터베이스 커넥터/래퍼를 사용하는 경우 매우 유용합니다.

생성자에서 연결 정보를 전달할 수 있습니다.최종 결정자 등이 아닌 소멸자를 사용할 수 있기 때문에 연결을 닫을 수 있습니다.그것은 더 편리하지만, 확실히 유용합니다.

예를 들어, PHP가 객체를 명시적으로 "자유롭게" 하기로 결정할 때(즉, 더 이상 사용되지 않음) 그 때 소멸자를 호출합니다.가비지 수집기가 실행되어 피니시저를 호출할 때까지 기다리지 않기 때문에 설명하는 시나리오에서 이 기능이 더 유용합니다.

$0.02

이안

<?php
class Database
{
    private $connection;
    private $cache = array();

    function __construct([$params])
    {
        //Connection here
    }

    //Query
    public function query(Query $Query)
    {
        if($this->is_cached($Query->checksum))
        {
            return $this->get_cache($Query->checksum);
        }
        //...
    }
    public function __destruct()
    {
        unset($this->connection);
        $this->WriteCache();
        unset($this->cache);
        shutdown_log($this,'Destruction Completed');
    }
}
?>

당신이 이해할 수 있는 예가 있습니다.

에서 반환한 fopen()들어 예들어, 로깅수, 사할있다니를 할 수 .__destruct() 하기 fclose()당신의 클래스가 파괴될 때 우리의 자원에 호출됩니다.

맞아요.__destruct짧은 실행 중인 php 스크립트에는 대부분 필요하지 않습니다.데이터베이스 연결, 파일 핸들 등은 스크립트 종료 시 닫히거나 변수가 범위를 벗어나는 경우 더 일찍 닫히기도 합니다.

제가 생각할 수 있는 한 가지 예는 데이터베이스에 로그를 쓰는 것입니다.스크립트 어딘가에 생성되는 로그 항목당 하나의 쿼리를 실행하고 싶지 않았기 때문에, 우리는 로깅 클래스의 __destruct에 "db에 쓰기" 부분을 작성하여 스크립트가 종료될 때 모든 것이 하나로 데이터베이스에 삽입되도록 했습니다.

다른 예:사용자에게 파일 업로드를 허용하는 경우 소멸자가 임시 파일을 삭제하는 데 좋은 위치가 될 수 있습니다(스크립트에서 문제가 발생한 경우에는 적어도 정리해야 함).

그러나 파일 핸들의 경우에도 유용할 수 있습니다.나는 객체로 포장된 오래된 오픈 등의 호출을 사용하는 애플리케이션을 작업했고 큰 파일 트리에서 호출을 사용할 때 php는 조만간 파일 핸들이 부족해질 것이기 때문에 스크립트가 실행되는 동안 청소하는 것이 좋을 뿐만 아니라 필요했습니다.

저는 많은 수의 "낮은 수준" 개체에 대해 APC 캐싱을 사용합니다. 그렇지 않으면 과도한 메모리를 사용할 수 있습니다. 그리고 스크립트 실행 중에 APC와 APC 간의 "낮은 수준" 개체의 읽기 및 쓰기를 처리하는 cacheCollection 개체가 있습니다.스크립트가 종료되면 APC에서 객체를 삭제해야 하므로 cacheCollection__destruct 메서드를 사용하여 해당 기능을 수행합니다.

사용한 적이 있습니다.__destruct()데이터베이스 연결을 래핑한 로깅 클래스:

<?php

class anyWrap
{
  private $obj,$calls,$log,$hooks;
  function anyWrap($obj, $logfile = NULL)
  {
       if(is_null($logfile))
       {
         $this->log = dirname(__FILE__) . "/../logs/wrapLog.txt";
       }
       $this->hooks = array();
       $this->dbCalls = 0;
       $this->obj = $obj;
  }

   public function __set($attri, $val) {
       $this->obj->$attri = $val;
   }

   public function __get($attri) {      
       return $this->obj->$attri;
   }
  public function __hook($method)
  {
   $this->hooks[] = $method;
  }


   public function __call($name,$args)
   {
       $this->calls++;
       if(in_array($name,$this->hooks))
       {
           file_put_contents($this->log,var_export($args,TRUE)."\r\n",FILE_APPEND);
       }
       return call_user_func_array(array($this->obj,$name),$args);
   }
   //On destruction log diagnostics
   public function __destruct()
   {
        unset($this->dbReal);
        file_put_contents($this->log,$this->calls."\r\n",FILE_APPEND);
   }
}

스크립트는 데이터베이스 호출에 연결하고 준비 문을 기록한 다음 스크립트가 끝까지 실행되면(언제나 실행되는지 알 수 없음) 데이터베이스 호출 수를 파일에 기록합니다.이렇게 하면 데이터베이스에서 특정 함수가 호출된 횟수를 확인하고 그에 따라 최적화를 계획할 수 있습니다.

MySQL 데이터베이스에서 PHP 스크립트를 사용하여 보기를 작성하는 경우, 스크립트 끝에서 해당 보기를 삭제해야 합니다.그렇지 않은 경우, 데이터베이스에 이미 유사한 이름의 보기가 있기 때문에 스크립트가 다음에 실행될 때 보기가 작성되지 않습니다.이를 위해 소멸자를 사용할 수 있습니다.

여기 해충과 같은 라이브러리들이 메소드 체인을 함수와 결합하거나, 다시 말해서, 함수에 대한 유창한 인터페이스를 달성하기 위해 사용하고 있다고 생각하는 파괴자에 대한 꽤 특이한 사용 사례가 있습니다. 다음과 같습니다.

<?php

class TestCase {
    private $message;
    private $closure;
    private $endingMessage;
    public function __construct($message, $closure) {
        $this->message = $message;
        $this->closure = $closure;
    }

    public function addEndingMessage($message) {
        $this->endingMessage = $message;
        return $this;
    }
    private function getClosure() {
        return $this->closure;
    }
    public function __destruct() {
        echo $this->message . ' - ';
        $this->getClosure()();
        echo  $this->endingMessage ? ' - ' . $this->endingMessage : '';
        echo "\r\n";
    }
}

function it($message, $closure) {
    return new TestCase($message, $closure);
}



it('ok nice', function() {
    echo 'what to do next?';
});//outputs: ok nice - what to do next?

it('ok fine', function() {
    echo 'what should I do?';
})->addEndingMessage('THE END');//outputs: ok fine - what should I do? - THE END

언급URL : https://stackoverflow.com/questions/3566155/php-destructors

반응형