Bir nesne nasıl yok edilir?


120

Bildiğim kadarıyla (ki bu çok az) iki yol var:

$var = new object()

Sonra:

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

Başka daha iyi bir yöntem mi? Burada saçlarımı mı bölüyorum?

Yanıtlar:


152

Arıyorsun unset().

Ancak bir nesneyi açıkça yok edemeyeceğinizi de hesaba katın.

Orada kalacaktır, ancak nesneyi kaldırırsanız ve betiğiniz PHP'yi bellek sınırlarına kadar zorlarsa, ihtiyaç duyulmayan nesneler çöp olarak toplanır. Daha unset()iyi performansa sahip olduğu için (test edilmemiş ancak PHP resmi kılavuzundaki yorumlardan birinde belgelenmiş) göründüğü için (boş olarak ayarlamanın aksine) devam ederdim .

Bununla birlikte, PHP'nin her zaman, sayfa sunulur sunulmaz nesneleri yok ettiğini unutmayın. Bu nedenle, bu yalnızca gerçekten uzun döngüler ve / veya yoğun sayfalarda gerekli olmalıdır.


1
Frankie Diyorum ki, kullandığınızda C ++, gelen newbir defa, o zaman gerekir kullanmak deletekez. Bu PHP'de doğru değil mi? Nesneye artık ihtiyaç kalmadığında otomatik çöp toplama var mı?
gsamaras

3
@gsamaras bu doğru. Yine de sızıntılarınız olabilir ve arka plan yordamları veya benzerleri yapıyorsanız php'nin GC'si hakkında daha fazla bilgi okumalısınız. Sitelerin çoğunda istek o kadar kısa sürüyor ki önemli değil. php.net/manual/en/features.gc.refcounting-basics.php
Frankie

unset()Nesneye olan referansı kaldırır mı ?
Yousha Aleayoub

9

Bununla ilgili birkaç yanlış anlaşılmayı açıklayan kullanışlı bir gönderi:

Destructor'ı açıkça aramayın

Bu, yıkıcının nasıl çalıştığına dair birkaç yanlış anlamayı kapsar. PHP5 belgesine göre, onu açıkça çağırmak değişkeninizi gerçekten yok etmeyecektir:

PHP 5, C ++ gibi diğer nesne yönelimli dillerinkine benzer bir yıkıcı kavramı sunar. Yıkıcı yöntem, belirli bir nesneye başka referanslar kalmaz ya da kapatma dizisi sırasında herhangi bir sırada çağrılır.

Yukarıdaki gönderi, başka hiçbir şey ayrılan belleğe işaret etmediği sürece, değişkeni null olarak ayarlamanın bazı durumlarda çalışabileceğini belirtir.


2

Kısa cevap: İkisine de ihtiyaç var.

Doğru cevabın verildiğini hissediyorum ama minimum düzeyde. Evet genellikle unset () "hız" için en iyisidir, ancak belleği hemen geri almak istiyorsanız (CPU pahasına) null kullanmak istemelisiniz.

Bahsedilen diğerleri gibi, null olarak ayarlamak her şeyin geri alındığı anlamına gelmez, nesnenin yok edilmesini önleyecek paylaşılan bellek (klonlanmamış) nesnelere sahip olabilirsiniz. Dahası, diğerlerinin de söylediği gibi, nesneleri açıkça "yok edemezsiniz", bu yüzden yine de yapmaya çalışmamalısınız.

Hangisinin sizin için en iyisi olduğunu bulmanız gerekecek. Ayrıca __destruct () 'yi unset veya null ile çağrılacak bir nesne için kullanabilirsiniz, ancak dikkatli kullanılmalı ve başkalarının söylediği gibi asla doğrudan çağrılmamalıdır!

görmek:

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

NULL atamak ve ayarlanmadı arasındaki fark nedir?


0

Bu, bir nesneyi yok edemeyeceğinizin basit bir kanıtıdır, yalnızca ona olan bir bağlantıyı yok edebilirsiniz.

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

İadeler

2

Burada iş başında görün: https://eval.in/1054130


3
Doğru, $var2bir referans olan yok ettin $var. Şimdi siz de yok ediyorsunuz $varve nesneyi tutan başka referansların olmadığını varsayarsak, işiniz bitti.
i336_

4
Bir nesneyi yok etmiyorsunuz, nesneye bir işaretçiyi yok ediyorsunuz. Bu büyük bir fark.
Yevgeniy Afanasyev

1
Diğer dillerde bir nesneyi yok edebilirsiniz ve diğer tüm işaretçiler size istisnalar veya saçmalıklar verir, ancak bu php için bir durum değildir
Yevgeniy Afanasyev

1
Yok edemezsin. Nesneyi tutan bir referans yoksa, nesne çöp toplayıcı tarafından toplanmaya hazırdır. Ve çöp toplayıcıyı çalıştırmaya zorlayamazsınız.
Daniel

0

Yeni bir mysqli nesnesi oluşturduğunuz bir durumda olabilir.

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

ama nesneyi kapattıktan sonra bile

$MyConnection->close();

print_r()içeriğini kontrol etmek için kullanacaksanız $MyConnection, aşağıdaki gibi bir hata alırsınız:

Error:
mysqli Object

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

bu durumda kullanamazsınız, unlink()çünkü unlink()bir yol adı dizesi gerektirir, ancak bu durumda $MyConnectionbir Nesnedir.

Yani değerini null olarak ayarlamak için başka bir seçeneğiniz var:

$MyConnection = null;

şimdi işler beklediğiniz gibi doğru gidiyor. Değişkenin içinde herhangi bir içeriğiniz yok $MyConnectionve mysqli Object'i zaten temizlediniz.

Değişkeninizin değerini olarak ayarlamadan önce Object'i kapatmanız önerilen bir uygulamadır null.


-7

Ayarsız giderdim çünkü çöp toplayıcıya daha iyi bir ipucu verebilir, böylece bellek daha kısa sürede tekrar kullanılabilir hale gelebilir. Nesnenin işaret ettiği herhangi bir şeyin önce başka referanslara sahip olmasına veya önce ayarlanmamasına dikkat edin, aksi takdirde çöp toplayıcıyı beklemeniz gerekir, çünkü bu durumda onlara hiçbir tutamaç olmayacaktır.


16
Cevaplarınızı yedekleyecek kaynaklarınız yoksa, muhtemelen "olabileceğini" düşündüğünüz şeyleri yayınlamamalısınız. Faydalı değildir ve bu tür yanlış bilgilerin doğru olarak algılanmasına ve tekrarlanmasına yol açar.
meagar

1
@meagar, yorumlarda unset () 'i null ile karşılaştıran örnek bir testin bulunduğu resmi kılavuz sayfasına bağlanmamın tam nedeni budur.
Frankie
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.