オブジェクトを破壊する方法は?


120

私の知る限り(これはごくわずかです)には、次の2つの方法があります。

$var = new object()

次に:

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

他のより良い方法?ここで髪の毛を割っていますか?

回答:


152

あなたが探していunset()ます。

ただし、オブジェクトを明示的に破棄することはできないことを考慮してください。

それはそこに残りますが、オブジェクトの設定を解除し、スクリプトがPHPをメモリ制限にプッシュすると、不要なオブジェクトはガベージコレクションされます。私は行くだろうunset()、より良いパフォーマンスを持っているようだとして(上でテストが、文書化されていません(ヌルに設定すると対照的に)コメントの1 PHP公式マニュアルより)。

ただし、ページが提供されるとすぐに、PHPは常にオブジェクトを破棄することに注意してください。したがって、これは本当に長いループや負荷の高いページでのみ必要です。


1
フランキーだから、私は、我々が使用する場合、C ++、から来new一度、我々はしなければならない使用deleteに一度。これはPHPでは当てはまりませんか?オブジェクトが不要になったときに自動ガベージコレクションがありますか?
gsamaras 2015

3
それは本当です@gsamaras。ただし、リークが発生する可能性もあります。デーモンなどを使用している場合は、phpのGCで詳細を読む必要があります。ほとんどのサイトでは、要求は非常に短期間であり、問​​題ではありません。php.net/manual/en/features.gc.refcounting-basics.php
フランキー

DOESは、unset()オブジェクトへの参照を削除しますか?
Yousha Aleayoub 2017

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_ 2018

4
オブジェクトを破壊するのではなく、オブジェクトへのポインタを破壊します。大きな違いです。
Yevgeniy Afanasyev 2018

1
他の言語ではオブジェクトを破棄でき、他のすべてのポインターは例外やゴミを出しますが、phpの場合はそうではありません
Yevgeniy Afanasyev

1
破壊することはできません。オブジェクトを保持する参照がない場合、オブジェクトはガベージコレクターによって収集される準備ができています。また、ガベージコレクターを強制的に実行することはできません。
ダニエル

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オブジェクトがあります。

したがって、その値をnullに設定する別の選択肢があります。

$MyConnection = null;

予想通り、今はうまくいきます。変数内にはコンテンツがなく$MyConnection、mysqliオブジェクトはすでにクリーンアップされています。

変数の値をに設定する前に、オブジェクトを閉じることをお勧めしますnull


-7

ガベージコレクターにより良いヒントを与えてメモリをより早く利用できるようにするため、私はunsetを使用します。オブジェクトが他の参照を持っていることを指すか、最初に設定が解除されることに注意してください。そうしないと、ハンドルがなくなるため、ガベージコレクターで待機する必要があります。


16
実際に回答をバックアップするための情報源がない限り、おそらく「発生する可能性がある」と思われることを投稿しないでください。それは役に立たず、この種の誤報が真実と見なされて繰り返されることになります。
貧弱

1
@meagarは、コメントにunset()をnullと比較するサンプルテストがある公式のマニュアルページにリンクした正確な理由です。
フランキー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.