Periksa apakah var sudah ada sebelum menghapus pengaturan di PHP?

89

Dengan pelaporan kesalahan aktif, atau bahkan untuk praktik terbaik, saat menghapus variabel dalam PHP, haruskah Anda memeriksa untuk melihat apakah variabel itu ada terlebih dahulu (dalam hal ini tidak selalu ada) dan membatalkannya, atau hanya menghapusnya?

<?PHP
if (isset($_SESSION['signup_errors'])){
    unset($_SESSION['signup_errors']);
}

// OR

unset($_SESSION['signup_errors']);
?>
JasonDavis
sumber
2
Cf. dk2.php.net/unset#77310
jensgram
1
Ini lebih efisien untuk NOTdigunakan isset. Lihat jawaban saya. Saya telah melakukan tes untuk menemukan perbedaan kecepatan.
Dan Bray

Jawaban:

171

Hapus saja, jika tidak ada, tidak ada yang akan dilakukan.

João Silva
sumber
3
Saya tidak tahu apakah itu akan memberikan peringatan atau pemberitahuan
JasonDavis
20
@SilentGhost Saya setuju, ini tampaknya tes yang sederhana, tetapi mereka meminta nasihat profesional, dan meskipun log kesalahan mungkin tidak memiliki kesalahan / peringatan / pemberitahuan apa pun yang tidak menetapkan var yang tidak ditentukan, mungkin ada masalah lain yang tidak dicatat. misalnya hanya memanggil unset berarti PHP menyapu SEMUA data var karena tidak dapat menemukan apa pun, sedangkan menggunakan if setmungkin memiliki skema pengindeksan yang lebih baik. (Sebagai contoh, yang sebelumnya mungkin tukang sepatu dan kedua pendekatan menggunakan metode pemeriksaan data yang sama).
James
Benar, dan itu juga lebih efisien. Lihatlah jawaban saya karena saya telah menguji kecepatan menggunakan issetayat yang tidak menggunakan isset.
Dan Bray
memilih ke bawah - Anda tidak dapat membatalkan kunci array yang tidak ditentukan.
Behnam
1
@jascha Saya berkata, kami tidak bisa!
Behnam
48

Dari Manual PHP :

Berkenaan dengan beberapa kebingungan sebelumnya dalam catatan ini tentang apa yang menyebabkan unset () memicu pemberitahuan saat menghapus variabel yang tidak ada ....

Variabel yang tidak ada, seperti di

<?php
unset($undefinedVariable);
?>

tidak memicu pemberitahuan "Variabel tidak ditentukan". Tapi

<?php
unset($undefinedArray[$undefinedKey]);
?>

memicu dua pemberitahuan, karena kode ini untuk membatalkan setel elemen array; baik $ undefinedArray maupun $ undefinedKey sendiri tidak disetel, mereka hanya digunakan untuk menemukan apa yang seharusnya tidak disetel. Lagipula, jika mereka memang ada, Anda masih berharap mereka berdua ada setelahnya. Anda TIDAK ingin seluruh array Anda menghilang hanya karena Anda unset () salah satu elemennya!

Tuan Smith
sumber
42
Ini membutuhkan lebih banyak klarifikasi. Anda dapat membatalkan kunci array yang tidak ditentukan selama array itu sendiri ada.
kingmaple
@kristovaher Memang - ini tidak membahas skenario spesifik yang dijelaskan OP sama sekali.
Mark Amery
23

Menggunakan unsetpada variabel yang tidak ditentukan tidak akan menyebabkan kesalahan apa pun (kecuali variabel tersebut adalah indeks dari larik (atau objek) yang tidak ada).

Oleh karena itu, satu-satunya hal yang perlu Anda pertimbangkan, adalah apa yang paling efisien. Lebih efisien untuk tidak menguji dengan 'isset', seperti yang akan ditunjukkan oleh pengujian saya.

Uji:

function A()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        unset($defined);
    }
}

function B()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        unset($undefined);
    }
}

function C()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        if (isset($defined))
            unset($defined);
    }
}

function D()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        if (isset($undefined))
            unset($undefined);
    }
}

$time_pre = microtime(true);
A();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function A time = $exec_time ";

$time_pre = microtime(true);
B();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function B time = $exec_time ";

$time_pre = microtime(true);
C();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function C time = $exec_time ";

$time_pre = microtime(true);
D();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function D time = $exec_time";
exit();

Hasil:

  1. Function A time = 1.0307259559631
    • Didefinisikan tanpa isset
  2. Function B time = 0.72514510154724
    • Tidak ditentukan tanpa isset
  3. Function C time = 1.3804969787598
    • Didefinisikan menggunakan isset
  4. Function D time = 0.86475610733032
    • Tidak ditentukan menggunakan isset

Kesimpulan:

Itu selalu kurang efisien untuk digunakan isset, belum lagi jumlah waktu ekstra yang dibutuhkan untuk menulis. Lebih cepat mencoba unsetvariabel tak terdefinisi daripada memeriksa apakah bisa unset.

Dan Bray
sumber
1
Ini jauh lebih baik daripada jawaban yang diterima! Terima kasih telah menjalankan tes ini.
Adam Friedman
3

Jika Anda ingin menghapus variabel maka Anda dapat menggunakan unset

unset($any_variable); // bool, object, int, string etc

Memeriksa keberadaannya tidak ada manfaatnya saat mencoba menghapus variabel.

Jika variabel adalah array dan Anda ingin menghapus elemen, Anda harus memastikan induknya ada terlebih dahulu, ini juga berlaku untuk properti objek.

unset($undefined_array['undefined_element_key']); // error - Undefined variable: undefined_array

unset($undefined_object->undefined_prop_name); // error - Undefined variable: undefined_object

Ini mudah dipecahkan dengan membungkus unsetdalam if(isset($var)){ ... }blok.

if(isset($undefined_array)){
    unset($undefined_array['undefined_element_key']); 
}

if(isset($undefined_object)){
    unset($undefined_object->undefined_prop_name); 
}

Alasan kita hanya memeriksa variabel ( induk ) adalah karena kita tidak perlu memeriksa properti / elemen dan melakukannya akan jauh lebih lambat untuk menulis dan menghitung karena akan menambah pemeriksaan ekstra.

if(isset($array)){
...
}

if(isset($object)){
...
}

.vs

$object->prop_name = null;
$array['element_key'] = null;

// This way elements/properties with the value of `null` can still be unset.

if(isset($array) && array_key_exists('element_key', $array)){
...
}

if(isset($object) && property_exists($object, 'prop_name')){
...
}

// or 

// This way elements/properties with `null` values wont be unset.

if(isset($array) && $array['element_key'])){
...
}

if(isset($object) && $object->prop_name)){
...
}

Hal ini tidak perlu dikatakan lagi, tetapi penting juga bahwa Anda mengetahui typevariabel saat mendapatkan, menyetel dan membatalkan setelan elemen atau properti; menggunakan sintaks yang salah akan menimbulkan kesalahan.

Itu sama ketika mencoba untuk membatalkan nilai array atau objek multidimensi. Anda harus memastikan kunci / nama orang tua ada.

if(isset($variable['undefined_key'])){
    unset($variable['undefined_key']['another_undefined_key']);
}

if(isset($variable->undefined_prop)){
    unset($variable->undefined_prop->another_undefined_prop);
}

Ketika berhadapan dengan objek, ada hal lain yang perlu dipikirkan, yaitu visibilitas.

Hanya karena ada tidak berarti Anda memiliki izin untuk memodifikasinya.

TarranJones
sumber
Akhirnya, jawaban yang tepat. Terima kasih.
wp78de
Pembaruan kecil: Dalam PHP 7.4 / 8.0 tidak ada kesalahan yang dilemparkan saat Anda unsetmemiliki properti objek induk yang tidak ada. Namun, mengganggu kunci dalam array yang tidak ada di PHP8 tidak hanya menimbulkan pemberitahuan tetapi juga peringatan (dapat berubah).
wp78de
1

Periksa tautan ini https://3v4l.org/hPAto

Alat online menunjukkan kompatibilitas kode untuk berbagai versi PHP

Menurut alat ini kodenya

unset($_SESSION['signup_errors']);

akan berfungsi untuk PHP> = 5.4.0 tanpa memberi Anda pemberitahuan / peringatan / kesalahan.

evgpisarchik
sumber