Php 소멸자
수업에서 __destruct를 사용해야 할 때의 실제 사례를 보여주세요.
좋아, 내 마지막 답변이 분명 맞지 않았기 때문에 다시 시도 해보자. 이 주제에 대한 많은 리소스와 예제가 인터넷에 있습니다. 다른 프레임 워크의 코드를 약간 검색하고 찾아 보면 꽤 좋은 예제를 볼 수 있습니다.
PHP가 종료시 리소스를 닫는다 고해서 더 이상 필요하지 않을 때 (또는 닫지 않는 것이 좋다) 명시 적으로 닫는 것이 나쁘다는 것을 의미하지는 않습니다. 사용 사례에 따라 다릅니다 ( 끝까지 사용 중인지 아니면 초기에 한 번의 호출이 있고 나머지 실행 동안 다시 필요하지 않은지 여부) ...
이제 __destruct
객체가 파괴 될 때 호출 된다는 것을 알고 있습니다. 논리적으로 객체가 파괴되면 어떻게됩니까? 음, 더 이상 사용할 수 없다는 뜻입니다. 따라서 리소스가 열려있는 경우 해당 리소스가 파괴 될 때 닫는 것이 합리적이지 않습니까? 물론 평균적인 웹 페이지에서 페이지는 곧 종료 될 것이므로 PHP가 페이지를 닫는 것은 일반적으로 끔찍하지 않습니다. 그러나 어떤 이유로 스크립트가 오래 실행되면 어떻게됩니까? 그런 다음 리소스 누출이 있습니다. 그렇다면 더 이상 필요하지 않을 때 (또는 더 이상 사용할 수없는 소멸자의 범위를 고려할 때) 모든 것을 닫는 것은 어떨까요?
다음은 실제 프레임 워크의 몇 가지 예입니다.
- 리튬의 Lithium \ net \ Socket 클래스
- Kohana의 Memcached 드라이버
- Joomla의 FTP 구현
- Zend Frameworks의 SMTP 메일 전송 클래스
- CodeIgniter의 TTemplate 클래스
- 케이크를위한 깔끔한 필터 도우미
- Symfony 세션 클래스에 소멸자를 사용하는 것에 대한 Google 그룹스 스레드
흥미로운 점은 Kohana가 태그를 추적하여 나중에 캐시를 지우는 대신 "네임 스페이스"로 삭제할 수 있다는 것입니다. 따라서 소멸자를 사용하여 이러한 변경 사항을 하드 스토리지에 플러시합니다.
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
}
};
이것이 destruct를 사용하는 좋은 이유입니다. 세션 소스에 대한 읽기 및 쓰기를 항상 방지하고 시작과 끝에서만이 작업을 수행합니다.
영화 정보 jpg 파일을 생성 할 PHP 페이지를 만듭니다. 이 페이지는 jpg로 변환하기 전에 몇 가지 정보를 수집하고 inkscape를 실행하여 템플릿 (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()
.
You are right, __destruct
is mostly unnecessary for the short running php scripts. Database connections, file handles and so on close on script exit or sometimes even earlier if variables run out of scope.
One example i can think of is writing logs to the database. Since we didn't want to fire one query per log entry that gets created somewhere in the script we wrote the "write to db" part in the __destruct of the logging class so when the script ends everything gets inserted into the database at one.
Another example: If you allow a user to upload files the destructor is sometimes a nice places to delete the temp file (in case something goes wrong in the script it at least get cleaned up)
But even for filehandles it can be useful. I've worked on a application that did use the old fopen etc. calls wrapped in objects and when using those on large filetrees php would run out of filehandles sooner or later, so cleaning up while the script was running was not only nice but necessary.
I use APC caching for large numbers of "low level" objects, that otherwise would use excessive memory; and I have a cacheCollection object that handles the reading and writing of those "low level" objects to and from APC during execution of the script. When the script terminates, the objects must be cleared down from APC, so I use the cacheCollection __destruct method to perform that function.
I have used __destruct()
in a logging class that wrapped a database connection:
<?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);
}
}
The script hooks into the database calls and logs the prepare statements, then when the script has run to an end (I don't always know when) it will finally log the number of calls to the database to the file. This way I can see how many times certain functions has been called on the database and plan my optimization accordingly.
If you are creating a view using a PHP script in a MySQL database, you must drop that view at the end of the script. Because if not, the next time that script is executed view will not be created, as there is already a view of similar name in the database. For this purpose you can use destructor.
참고URL : https://stackoverflow.com/questions/3566155/php-destructors
'Program Tip' 카테고리의 다른 글
C # 열거 형 : Nullable 또는 'Unknown'값? (0) | 2020.12.01 |
---|---|
MVVM : 라디오 버튼을 뷰 모델에 바인딩합니까? (0) | 2020.12.01 |
Go 객체의 포인터 값을 어떻게 인쇄합니까? (0) | 2020.12.01 |
부트 스트랩의 clearfix 클래스 이해 (0) | 2020.12.01 |
Visual C ++ 2008에서 UTF-8 문자열 리터럴을 만드는 방법 (0) | 2020.12.01 |