Bagaimana cara menghancurkan suatu benda?

120

Sejauh yang saya tahu (yang sangat sedikit), ada dua cara, diberikan:

$var = new object()

Kemudian:

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

Metode lain yang lebih baik? Apakah saya membelah rambut di sini?

PandemoniumSyndicate
sumber

Jawaban:

152

Anda sedang mencari unset().

Tetapi pertimbangkan bahwa Anda tidak dapat secara eksplisit menghancurkan suatu objek.

Ini akan tetap di sana, namun jika Anda membatalkan setel objek dan skrip Anda mendorong PHP ke batas memori, objek yang tidak diperlukan akan dikumpulkan sampahnya. Saya akan menggunakan unset()(sebagai lawan mengaturnya ke nol) karena tampaknya memiliki kinerja yang lebih baik (tidak diuji tetapi didokumentasikan di salah satu komentar dari manual resmi PHP).

Karena itu, perlu diingat bahwa PHP selalu menghancurkan objek segera setelah halaman disajikan. Jadi ini hanya diperlukan pada loop yang sangat panjang dan / atau halaman intensif yang berat.

Frankie
sumber
1
Jadi Frankie, saya berasal dari C ++, di mana jika kita menggunakan newsekali, maka kita harus menggunakan deletesekali. Ini tidak benar di PHP? Ada pengumpulan sampah otomatis saat objek tidak lagi dibutuhkan?
gsamaras
3
@gsamaras itu benar. Anda juga dapat mengalami kebocoran, dan Anda harus membaca lebih lanjut tentang GC php jika Anda melakukan daemon atau yang serupa. Di sebagian besar situs, permintaan berlangsung sangat singkat sehingga tidak menjadi masalah. php.net/manual/en/features.gc.refcounting-basics.php
Frankie
Apakah unset()menghapus referensi ke Objek?
Yousha Aleayoub
9

Posting praktis yang menjelaskan beberapa kesalahpahaman tentang ini:

Jangan Panggil The Destructor secara eksplisit

Ini mencakup beberapa kesalahpahaman tentang cara kerja destruktor. Memanggilnya secara eksplisit tidak akan benar-benar merusak variabel Anda, menurut dokumen PHP5:

PHP 5 memperkenalkan konsep destruktor yang mirip dengan bahasa berorientasi objek lainnya, seperti C ++. Metode destruktor akan dipanggil segera setelah tidak ada referensi lain ke objek tertentu, atau dalam urutan apa pun selama urutan shutdown.

Posting di atas menyatakan bahwa pengaturan variabel ke null dapat berfungsi dalam beberapa kasus, selama tidak ada yang mengarah ke memori yang dialokasikan.

sturrockad
sumber
2

Jawaban singkatnya: Keduanya dibutuhkan.

Saya merasa seperti jawaban yang benar diberikan tetapi minimal. Ya umumnya unset () paling baik untuk "kecepatan", tetapi jika Anda ingin mendapatkan kembali memori segera (dengan biaya CPU) harus ingin menggunakan null.

Seperti yang disebutkan orang lain, menyetel ke nol tidak berarti semuanya diambil kembali, Anda dapat memiliki objek memori bersama (tidak dikloning) yang akan mencegah kerusakan objek. Selain itu, seperti yang dikatakan orang lain, Anda tidak dapat "menghancurkan" objek secara eksplisit sehingga Anda tidak boleh mencoba melakukannya.

Anda perlu mencari tahu mana yang terbaik untuk Anda. Anda juga dapat menggunakan __destruct () untuk objek yang akan dipanggil saat tidak disetel atau null tetapi harus digunakan dengan hati-hati dan seperti yang dikatakan orang lain, jangan pernah dipanggil secara langsung!

Lihat:

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

Apa perbedaan antara menetapkan NULL dan unset?

Mike Q
sumber
0

Ini adalah bukti sederhana bahwa Anda tidak dapat menghancurkan suatu objek, Anda hanya dapat menghancurkan tautannya.

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

kembali

2

Lihat aksinya di sini: https://eval.in/1054130

Yevgeniy Afanasyev
sumber
3
Benar, Anda telah menghancurkan $var2yang merupakan referensi $var. Sekarang Anda menghancurkan $varjuga dan, dengan anggapan tidak ada referensi lain yang memegang benda itu, Anda sudah selesai.
i336_
4
Anda tidak menghancurkan sebuah objek, Anda menghancurkan penunjuk ke objek tersebut. Ini adalah perbedaan yang besar.
Yevgeniy Afanasyev
1
Dalam bahasa lain Anda dapat menghancurkan suatu objek dan semua petunjuk lainnya akan memberi Anda pengecualian atau sampah, tetapi tidak demikian halnya untuk php
Yevgeniy Afanasyev
1
Anda tidak bisa menghancurkan. Jika tidak ada referensi yang menahan objek, maka objek tersebut siap untuk diambil oleh pengumpul sampah. Dan Anda tidak bisa memaksa menjalankan pengumpul sampah.
Daniel
0

Mungkin dalam situasi di mana Anda membuat objek mysqli baru.

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

tetapi bahkan setelah Anda menutup objek

$MyConnection->close();

jika Anda akan menggunakan print_r()untuk memeriksa konten $MyConnection, Anda akan mendapatkan kesalahan seperti di bawah ini:

Error:
mysqli Object

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

dalam hal ini Anda tidak dapat menggunakan unlink()karena unlink()akan memerlukan string nama jalur tetapi dalam kasus ini $MyConnectionadalah Objek.

Jadi, Anda memiliki pilihan lain untuk menyetel nilainya menjadi null:

$MyConnection = null;

sekarang semuanya berjalan baik, seperti yang Anda harapkan. Anda tidak memiliki konten apa pun di dalam variabel $MyConnectionserta Anda sudah membersihkan Objek mysqli.

Ini adalah praktik yang disarankan untuk menutup Objek sebelum menyetel nilai variabel Anda ke null.

Subrat Kumar Palhar
sumber
-7

Saya akan pergi dengan tidak disetel karena itu mungkin memberi pengumpul sampah petunjuk yang lebih baik sehingga memori dapat tersedia lagi lebih cepat. Berhati-hatilah bahwa setiap hal yang ditunjukkan objek memiliki referensi lain atau tidak disetel terlebih dahulu atau Anda benar-benar harus menunggu di pengumpul sampah karena tidak akan ada pegangan untuk mereka.

hackartist
sumber
16
Kecuali jika Anda benar-benar memiliki sumber untuk mendukung jawaban Anda, Anda mungkin tidak boleh memposting apa yang menurut Anda "mungkin" terjadi. Ini tidak berguna dan menyebabkan kesalahan informasi semacam ini dianggap sebagai kebenaran dan diulangi.
meagar
1
@meagar itulah alasan yang tepat mengapa saya menautkan ke halaman manual resmi di mana, di komentar, ada contoh tes yang membandingkan unset () dengan null.
Frankie