물체를 파괴하는 방법?


120

내가 아는 한 (매우 적음) 두 가지 방법이 있습니다.

$var = new object()

그때:

// Method 1: Set to null
$var = null;
// Method 2: Unset 
unset($var); 

다른 더 나은 방법? 여기서 머리카락을 쪼개고 있습니까?

답변:


152

당신은을 찾고 있습니다 unset().

그러나 객체를 명시 적으로 파괴 할 수 없다는 점을 고려하십시오 .

그러나 객체를 설정 해제하고 스크립트가 PHP를 메모리 제한으로 푸시하면 필요하지 않은 객체가 가비지 수집됩니다. unset()더 나은 성능을 가진 것처럼 보이기 때문에 (null로 설정하는 대신) 함께 갈 것입니다 (테스트되지 않았지만 PHP 공식 매뉴얼 의 주석 중 하나에 문서화 됨 ).

즉, PHP는 페이지가 제공되 자마자 항상 객체를 파괴한다는 점을 명심하십시오. 따라서 이것은 매우 긴 루프 및 / 또는 집중적 인 페이지에서만 필요합니다.


1
Frankie, 저는 C ++에서 왔는데 new, 한 번 사용 하면 한 번만 사용해야합니다delete . 이것은 PHP에서 사실이 아닙니다. 객체가 더 이상 필요하지 않을 때 자동 가비지 수집이 있습니까?
gsamaras

3
@gsamaras 사실입니다. 하지만 누출이있을 수도 있으며 데몬이나 유사한 작업을 수행하는 경우 php의 GC에 대해 자세히 읽어야합니다. 대부분의 사이트에서 요청이 너무 짧아서 중요하지 않습니다. php.net/manual/en/features.gc.refcounting-basics.php
프랭키

unset()객체에 대한 참조를 제거 합니까 ?
Yousha Aleayoub

9

이에 대한 몇 가지 오해를 설명하는 편리한 게시물 :

소멸자를 명시 적으로 호출하지 마십시오.

여기에는 소멸자가 작동하는 방식에 대한 몇 가지 오해가 포함됩니다. PHP5 문서에 따르면 명시 적으로 호출해도 실제로 변수가 파괴되지는 않습니다.

PHP 5에는 C ++와 같은 다른 객체 지향 언어와 유사한 소멸자 개념이 도입되었습니다. 소멸자 메서드는 특정 개체에 대한 다른 참조가없는 즉시 또는 종료 시퀀스 동안 임의의 순서로 호출됩니다.

위의 게시물은 할당 된 메모리를 가리키는 다른 항목이없는 한 경우에 따라 변수를 null로 설정하면 작동 할 수 있다고 설명합니다.


2

짧은 대답 : 둘 다 필요합니다.

나는 정답이 주어졌지만 최소한으로 느낀다. 예, 일반적으로 unset ()은 "속도"에 가장 적합하지만 메모리를 즉시 회수하려면 (CPU 비용으로) null을 사용해야합니다.

언급 된 다른 사람들과 마찬가지로 null로 설정한다고해서 모든 것이 회수되는 것은 아니며, 객체의 파괴를 방지하는 공유 메모리 (복제되지 않은) 객체를 가질 수 있습니다. 더욱이 다른 사람들이 말했듯이 명시 적으로 객체를 "파괴"할 수 없기 때문에 어차피 시도해서는 안됩니다.

자신에게 가장 적합한 것이 무엇인지 파악해야합니다. 또한 unset 또는 null에서 호출 될 객체에 대해 __destruct ()를 사용할 수 있지만 신중하게 사용해야하며 다른 사람들이 말했듯이 직접 호출되지 않아야합니다!

보다:

http://www.stoimen.com/blog/2011/11/14/php-dont-call-the-destructor-explicitly/

NULL 할당과 설정 해제의 차이점은 무엇입니까?


0

이것은 당신이 객체를 파괴 할 수 없다는 것을 증명하는 간단한 증명입니다. 당신은 그 객체에 대한 링크 만 파괴 할 수 있습니다.

$var = (object)['a'=>1];
$var2 = $var;
$var2->a = 2;
unset($var2);
echo $var->a;

보고

2

여기에서 실제 동작을 확인하세요 : https://eval.in/1054130


3
오른쪽, 당신은 파괴 한 $var2참조이었다 $var. 이제 또한 파괴 $var하고 객체를 보유하는 다른 참조가 없다고 가정하면 완료됩니다.
i336_

4
객체를 파괴하는 것이 아니라 객체에 대한 포인터를 파괴하는 것입니다. 큰 차이입니다.
Yevgeniy Afanasyev

1
다른 언어에서는 객체를 파괴 할 수있는 다른 모든 포인터는 당신에게 예외 또는 쓰레기를 줄 것이다,하지만 PHP를위한 경우가 아니다
예브게니 Afanasyev

1
파괴 할 수 없습니다. 개체를 보유하는 참조가 없으면 가비지 수집기가 개체를 수집 할 준비가 된 것입니다. 그리고 가비지 수집기를 강제로 실행할 수 없습니다.
Daniel

0

새로운 mysqli 객체를 생성하는 상황 일 수 있습니다.

$MyConnection = new mysqli($hn, $un, $pw, $db);

하지만 물체를 닫은 후에도

$MyConnection->close();

을 (를) 사용 print_r()하여의 내용을 확인하면 다음과 $MyConnection같은 오류가 발생합니다.

Error:
mysqli Object

Warning: print_r(): Property access is not allowed yet in /path/to/program on line ..
( [affected_rows] => [client_info] => [client_version] =>.................)

이 경우 경로 이름 문자열이 필요 하기 unlink()때문에 사용할 수 없지만 unlink()이 경우 $MyConnection에는 Object입니다.

따라서 값을 null로 설정하는 또 다른 선택이 있습니다.

$MyConnection = null;

이제 예상대로 일이 올바르게 진행됩니다. $MyConnection이미 mysqli 객체를 정리 한 것만 큼 변수 안에 내용이 없습니다 .

변수 값을로 설정하기 전에 개체를 닫는 것이 좋습니다 null.


-7

메모리를 더 빨리 다시 사용할 수 있도록 가비지 수집기에 더 나은 힌트를 줄 수 있으므로 설정하지 않은 상태로 갈 것입니다. 객체가 가리키는 모든 것이 다른 참조를 갖거나 먼저 설정 해제되거나 가비지 수집기에서 핸들이 없기 때문에 실제로 기다려야합니다.


16
실제로 답변을 뒷받침 할 출처가없는 한 "가능성"이라고 생각하는 것을 게시해서는 안됩니다. 그것은 유용하지 않으며 이런 종류의 잘못된 정보가 진실로 받아 들여지고 반복되게합니다.
meagar

1
@meagar가 공식 매뉴얼 페이지에 링크 한 정확한 이유입니다. 주석에서 unset ()을 null과 비교하는 샘플 테스트가 있습니다.
Frankie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.