Cara terbaik untuk menguji keberadaan variabel di PHP; isset () jelas rusak

187

Dari isset()dokumen :

isset() will return FALSE if testing a variable that has been set to NULL.

Pada dasarnya, isset()tidak memeriksa apakah variabel diatur sama sekali, tetapi apakah itu diatur ke apa pun kecuali NULL.

Mengingat itu, apa cara terbaik untuk benar-benar memeriksa keberadaan suatu variabel? Saya mencoba sesuatu seperti:

if(isset($v) || @is_null($v))

( @diperlukan untuk menghindari peringatan ketika $vtidak disetel) tetapi is_null()memiliki masalah yang mirip dengan isset(): ia mengembalikan TRUEvariabel yang tidak disetel! Tampaknya juga:

@($v === NULL)

bekerja persis seperti @is_null($v), jadi itu juga keluar.

Bagaimana kita seharusnya memeriksa keberadaan variabel dalam PHP?


Sunting: jelas ada perbedaan dalam PHP antara variabel yang tidak disetel, dan variabel yang diatur ke NULL:

<?php
$a = array('b' => NULL);
var_dump($a);

PHP menunjukkan bahwa $a['b']ada, dan memiliki NULLnilai. Jika Anda menambahkan:

var_dump(isset($a['b']));
var_dump(isset($a['c']));

Anda dapat melihat ambiguitas yang saya bicarakan dengan isset()fungsi. Inilah output dari ketiganya var_dump()s:

array(1) {
  ["b"]=>
  NULL
}
bool(false)
bool(false)

Sunting lebih lanjut: dua hal.

Satu, kasus penggunaan. Array diubah menjadi data UPDATEpernyataan SQL , di mana kunci array adalah kolom tabel, dan nilai array adalah nilai yang akan diterapkan ke setiap kolom. Setiap kolom tabel dapat menyimpan NULLnilai, yang ditandai dengan meneruskan NULLnilai dalam array. Anda memerlukan cara untuk membedakan antara kunci array yang tidak ada, dan nilai array yang diatur ke NULL; itulah perbedaan antara tidak memperbarui nilai kolom dan memperbarui nilai kolom menjadi NULL.

Kedua, jawaban Zoredache , array_key_exists()berfungsi dengan benar, untuk kasus penggunaan saya di atas dan untuk variabel global apa pun:

<?php
$a = NULL;
var_dump(array_key_exists('a', $GLOBALS));
var_dump(array_key_exists('b', $GLOBALS));

output:

bool(true)
bool(false)

Karena itu benar menangani hampir di mana-mana saya bisa melihat ada ambiguitas antara variabel yang tidak ada dan variabel yang diatur NULL, saya memanggil array_key_exists()cara termudah resmi dalam PHP untuk benar-benar memeriksa keberadaan suatu variabel .

(Hanya kasus lain yang bisa saya pikirkan adalah untuk properti kelas, yang ada di sana property_exists(), yang, menurut dokumennya , bekerja serupa dengan array_key_exists()di mana ia benar membedakan antara tidak diatur dan diatur ke NULL.)

chazomaticus
sumber
Anda tidak dapat memeriksa - tetapi mengapa Anda harus melakukannya?
terlalu banyak php
12
NULL memiliki arti yang sangat spesifik dalam PHP, dan ini merupakan konsep yang sepenuhnya terpisah dari apakah suatu variabel disetel atau tidak.
chazomaticus
33
ADA alasan untuk membedakan antara nol dan tidak ada. Misalnya, Anda sedang membangun objek untuk mewakili baris dalam tabel database. Untuk setiap kolom di baris, Anda membuat variabel pribadi, hanya dapat diakses melalui metode pengambil objek. Misalkan nilai kolom adalah nol. Sekarang, bagaimana metode pengambil itu mengetahui apakah tidak ada kolom seperti itu dalam tabel, atau apakah objek ini hanya memiliki nilai nol di sana? Untungnya, dalam kasus saya, variabel pribadi sebenarnya adalah entri dalam array pribadi, jadi saya dapat menggunakan array_key_exists, tetapi ini adalah masalah nyata.
Nathan Long
1
Sudah dihapus dari versi baru PHP, ya. Sayangnya, itu tidak hilang dari setiap penyebaran PHP. Selain itu, sepertinya detail semantik yang tidak ada gunanya untuk berdalih tentang apakah kita berbicara tentang elemen array atau variabel. Terlepas dari standar apa yang Anda pikir harus dipatuhi kode, penting untuk mengetahui cara mengatasi ketidakkonsistenan dalam bahasa PHP.
chazomaticus
2
@chazomaticus Tapi variabel dan elemen array secara fundamental berbeda ; hanya karena Anda dapat melakukan beberapa hal yang sama dengan mereka tidak berarti mereka atau harus 100% dipertukarkan. Tidak ada "ketidakkonsistenan dalam bahasa PHP" di sini, hanya sesuatu yang tidak Anda sukai / pahami. Adapun register_globals, saya masih berjuang untuk memikirkan situasi di mana bahkan itu akan membutuhkan perbedaan seperti itu, karena apa pun yang terdaftar dari permintaan HTTP akan selalu berupa string, bukan null.
IMSoP

Jawaban:

97

Jika variabel yang Anda periksa akan berada dalam lingkup global yang dapat Anda lakukan:

array_key_exists('v', $GLOBALS) 
Sakit kepala
sumber
3
Ah ha! SEKARANG kau bicara! Bagaimana Anda melakukannya untuk, katakanlah, properti kelas?
chazomaticus
22
Sebagai variasi, jika pemeriksaan perlu bekerja untuk variabel cakupan lokal juga, pada dapat melakukan $defined_vars = get_defined_vars();dan kemudian menguji melalui array_key_exists('v', $defined_vars);.
Henrik Opel
1
Ini terlihat agak jelek bagi saya, tetapi dalam kasus di mana Anda benar-benar memeriksa elemen array, itu jauh lebih masuk akal: isset($foo[$bar])menjadiarray_key_exists($bar, $foo)
Arild
property_existstampaknya menjanjikan, kecuali untuk ini:> Fungsi property_exists () tidak dapat mendeteksi properti yang dapat diakses secara ajaib menggunakan metode __get magic.
alexw
@alexw Variabel "dibuat" melalui __memang tidak ada. __get adalah kode arbitrer yang digunakan sebagai cadangan untuk variabel yang tidak ada, yang dapat mengembalikan apa pun yang diinginkan terlepas dari apakah ada data yang relevan yang pernah disimpan.
Brilliand
46

Mencoba memberikan ikhtisar dari berbagai diskusi dan jawaban:

Tidak ada jawaban tunggal untuk pertanyaan yang dapat menggantikan semua cara yang issetdapat digunakan. Beberapa kasus penggunaan ditangani oleh fungsi lain, sementara yang lain tidak tahan terhadap pengawasan, atau memiliki nilai yang meragukan di luar kode golf. Jauh dari menjadi "rusak" atau "tidak konsisten", kasus penggunaan lain menunjukkan mengapa issetreaksi terhadap nullperilaku logis.

Kasus penggunaan nyata (dengan solusi)

1. Array keys

Array dapat diperlakukan seperti kumpulan variabel, dengan unsetdan issetmemperlakukan mereka seolah-olah mereka. Namun, karena mereka dapat diulang, dihitung, dll, nilai yang hilang tidak sama dengan nilai yang nilainya null.

Jawabannya dalam hal ini, adalah menggunakan array_key_exists()alih-alihisset() .

Karena ini membutuhkan array untuk memeriksa sebagai argumen fungsi, PHP masih akan memunculkan "pemberitahuan" jika array itu sendiri tidak ada. Dalam beberapa kasus, secara sah dapat dikatakan bahwa setiap dimensi seharusnya diinisialisasi terlebih dahulu, sehingga pemberitahuan melakukan tugasnya. Untuk kasus lain, fungsi "rekursif" array_key_exists, yang memeriksa setiap dimensi array pada gilirannya, akan menghindari ini, tetapi pada dasarnya akan sama dengan @array_key_exists. Ini juga agak tangensial untuk penanganan nullnilai.

2. Properti objek

Dalam teori tradisional "Pemrograman Berorientasi Objek", enkapsulasi dan polimorfisme adalah sifat-sifat kunci dari objek; dalam implementasi OOP berbasis kelas seperti PHP, sifat dikemas dinyatakan sebagai bagian dari definisi kelas, dan diberikan tingkat akses ( public, protected, atau private).

Namun, PHP juga memungkinkan Anda untuk secara dinamis menambahkan properti ke objek, seperti Anda akan kunci ke array, dan beberapa orang menggunakan objek kelas-kurang (secara teknis, contoh built in stdClass, yang tidak memiliki metode atau fungsi pribadi) dalam cara yang sama cara untuk array asosiatif. Ini mengarah ke situasi di mana fungsi mungkin ingin tahu apakah properti tertentu telah ditambahkan ke objek yang diberikan padanya.

Seperti dengan kunci array, solusi untuk memeriksa properti objek termasuk dalam bahasa, cukup, disebutproperty_exists ,.

Kasus penggunaan yang tidak dapat dibenarkan, dengan diskusi

3. register_globals, dan polusi lain dari namespace global

The register_globalsfitur ditambahkan variabel ke lingkup global yang namanya ditentukan oleh aspek permintaan HTTP (GET dan POST parameter, dan cookie). Ini dapat menyebabkan kode buggy dan tidak aman, yang karenanya telah dinonaktifkan secara default sejak PHP 4.2, dirilis Agustus 2000 dan dihapus sepenuhnya dalam PHP 5.4, dirilis Mar 2012 . Namun, ada kemungkinan bahwa beberapa sistem masih berjalan dengan fitur ini diaktifkan atau ditiru. Dimungkinkan juga untuk "mencemari" namespace global dengan cara lain, menggunakan globalkata kunci, atau $GLOBALSarray.

Pertama, register_globalsitu sendiri tidak mungkin menghasilkan nullvariabel, karena nilai GET, POST, dan cookie akan selalu berupa string (dengan ''masih kembali truedari isset), dan variabel dalam sesi harus sepenuhnya di bawah kendali programmer.

Kedua, pencemaran suatu variabel dengan nilai nullhanya masalah jika ini berlebihan menulis beberapa inisialisasi sebelumnya. "Over-writing" suatu variabel yang tidak diinisialisasi dengan nullhanya akan menjadi masalah jika kode di tempat lain membedakan antara kedua negara, jadi dengan sendirinya kemungkinan ini adalah argumen untuk tidak membuat perbedaan seperti itu.

4. get_defined_varsdancompact

Beberapa fungsi yang jarang digunakan dalam PHP, seperti get_defined_varsdan compact, memungkinkan Anda untuk memperlakukan nama variabel seolah-olah mereka adalah kunci dalam array. Untuk variabel global, array super-global$GLOBALS memungkinkan akses yang sama, dan lebih umum. Metode akses ini akan berperilaku berbeda jika variabel tidak didefinisikan dalam ruang lingkup yang relevan.

Setelah Anda memutuskan untuk memperlakukan serangkaian variabel sebagai array menggunakan salah satu dari mekanisme ini, Anda dapat melakukan semua operasi yang sama di atasnya seperti pada array normal apa pun. Akibatnya, lihat 1.

Fungsionalitas yang ada hanya untuk memprediksi bagaimana fungsi-fungsi ini akan berperilaku (misalnya "apakah akan ada 'foo' kunci dalam array yang dikembalikan oleh get_defined_vars?") Adalah berlebihan, karena Anda dapat menjalankan fungsi dan mencari tahu tanpa efek buruk.

4a. Variabel variabel ( $$foo)

Meskipun tidak persis sama dengan fungsi yang mengubah set variabel menjadi array asosiatif, kebanyakan kasus menggunakan "variabel variabel" ("tetapkan ke variabel bernama berdasarkan variabel lain ini") dapat dan harus diubah untuk menggunakan array asosiatif sebagai gantinya .

Nama variabel, pada dasarnya, adalah label yang diberikan pada nilai oleh pemrogram; jika Anda menentukannya pada saat run-time, itu bukan benar-benar label tetapi kunci di beberapa toko nilai kunci. Lebih praktisnya, dengan tidak menggunakan array, Anda kehilangan kemampuan untuk menghitung, beralih, dll; itu juga bisa menjadi tidak mungkin untuk memiliki variabel "di luar" toko kunci-nilai, karena mungkin ditulis berlebihan oleh $$foo.

Setelah diubah untuk menggunakan array asosiatif, kode akan setuju untuk solusi 1. Akses properti objek tidak langsung (misalnya $foo->$property_name) dapat diatasi dengan solusi 2.

5. issetjauh lebih mudah untuk mengetik daripadaarray_key_exists

Saya tidak yakin ini benar-benar relevan, tapi ya, nama-nama fungsi PHP bisa sangat bertele-tele dan kadang-kadang tidak konsisten. Rupanya, versi PHP pra-sejarah menggunakan panjang nama fungsi sebagai kunci hash, jadi Rasmus sengaja membuat nama fungsi seperti htmlspecialcharssehingga mereka akan memiliki jumlah karakter yang tidak biasa ...

Tetap saja, setidaknya kita tidak menulis Java, kan? ;)

6. Variabel yang tidak diinisialisasi memiliki tipe

The halaman manual pada dasar-dasar variabel meliputi pernyataan ini:

Variabel yang tidak diinisialisasi memiliki nilai default tipenya tergantung pada konteks di mana mereka digunakan

Saya tidak yakin apakah ada beberapa gagasan di Zend Engine tentang "tipe belum diinisialisasi tetapi diketahui" atau apakah ini terlalu banyak membaca pernyataan itu.

Yang jelas adalah bahwa tidak ada perbedaan praktis untuk perilaku mereka, karena perilaku yang dijelaskan pada halaman itu untuk variabel tidak diinisialisasi identik dengan perilaku variabel yang nilainya null. Untuk memilih satu contoh, keduanya $adan $bdalam kode ini akan berakhir sebagai integer 42:

unset($a);
$a += 42;

$b = null;
$b += 42;

(Yang pertama akan memunculkan pemberitahuan tentang variabel yang tidak dideklarasikan, dalam upaya membuat Anda menulis kode yang lebih baik, tetapi tidak akan ada bedanya dengan bagaimana kode itu benar-benar berjalan.)

99. Mendeteksi jika suatu fungsi telah berjalan

(Menjaga yang terakhir ini, karena jauh lebih lama daripada yang lain. Mungkin aku akan mengeditnya nanti ...)

Pertimbangkan kode berikut:

$test_value = 'hello';
foreach ( $list_of_things as $thing ) {
    if ( some_test($thing, $test_value) ) {
        $result = some_function($thing);
    }
}
if ( isset($result) ) {
    echo 'The test passed at least once!';
}

Jika some_functionbisa kembali null, ada kemungkinan echotidak akan tercapai walaupun some_testdikembalikan true. Tujuan programmer adalah untuk mendeteksi kapan $resulttidak pernah diatur, tetapi PHP tidak mengizinkan mereka untuk melakukannya.

Namun, ada masalah lain dengan pendekatan ini, yang menjadi jelas jika Anda menambahkan loop luar:

foreach ( $list_of_tests as $test_value ) {
    // something's missing here...
    foreach ( $list_of_things as $thing ) {
        if ( some_test($thing, $test_value) ) {
            $result = some_function($thing);
        }
    }
    if ( isset($result) ) {
        echo 'The test passed at least once!';
    }
}

Karena $resulttidak pernah diinisialisasi secara eksplisit, itu akan mengambil nilai ketika tes pertama berlalu, sehingga tidak mungkin untuk mengetahui apakah tes berikutnya lulus atau tidak. Ini sebenarnya adalah bug yang sangat umum ketika variabel tidak diinisialisasi dengan benar.

Untuk memperbaikinya, kita perlu melakukan sesuatu di saluran tempat saya berkomentar bahwa ada sesuatu yang hilang. Solusi yang paling jelas adalah mengatur $resultke "nilai terminal" yang some_functiontidak pernah bisa kembali; jika ini null, maka sisa kode akan berfungsi dengan baik. Jika tidak ada kandidat alami untuk nilai terminal karena some_functionmemiliki tipe pengembalian yang sangat tidak dapat diprediksi (yang mungkin merupakan pertanda buruk pada dirinya sendiri), maka nilai boolean tambahan, misalnya $found, dapat digunakan sebagai gantinya.

Percobaan satu: very_nullkonstanta

PHP secara teoritis dapat memberikan konstanta khusus - dan juga null- untuk digunakan sebagai nilai terminal di sini; mungkin, akan ilegal untuk mengembalikan ini dari suatu fungsi, atau itu akan dipaksa null, dan hal yang sama mungkin berlaku untuk meneruskannya sebagai argumen fungsi. Itu akan membuat kasus yang sangat spesifik ini sedikit lebih sederhana, tetapi segera setelah Anda memutuskan untuk memfaktorkan ulang kode - misalnya, untuk meletakkan loop dalam ke dalam fungsi yang terpisah - itu akan menjadi tidak berguna. Jika konstanta dapat dilewati antar fungsi, Anda tidak dapat menjamin bahwa some_functiontidak akan mengembalikannya, sehingga tidak lagi berguna sebagai nilai terminal universal.

Argumen untuk mendeteksi variabel yang tidak diinisialisasi dalam kasus ini bermuara pada argumen untuk konstanta khusus itu: jika Anda mengganti komentar dengan unset($result), dan memperlakukannya secara berbeda dari $result = null, Anda memperkenalkan "nilai" untuk $resultyang tidak dapat diteruskan, dan hanya dapat terdeteksi oleh fungsi bawaan tertentu.

Percobaan dua pemikiran: penugasan tugas

Cara lain untuk berpikir tentang apa yang terakhir ifditanyakan adalah "apakah ada yang membuat tugas $result?" Daripada menganggapnya sebagai nilai khusus $result, Anda mungkin bisa menganggap ini sebagai "metadata" tentang variabel, sedikit mirip dengan "variabel tainting" Perl. Jadi, daripada issetAnda mungkin menyebutnya has_been_assigned_to, dan bukan unset, reset_assignment_state.

Tetapi jika demikian, mengapa berhenti di boolean? Bagaimana jika Anda ingin tahu berapa kali tes lulus; Anda cukup memperluas metadata ke bilangan bulat dan memiliki get_assignment_countdan reset_assignment_count...

Tentunya, menambahkan fitur seperti itu akan memiliki kompromi dalam kompleksitas dan kinerja bahasa, sehingga perlu dipertimbangkan dengan hati-hati terhadap manfaat yang diharapkan. Seperti very_nullkonstanta, ini akan berguna hanya dalam keadaan yang sangat sempit, dan akan sama-sama tahan terhadap re-factoring.

Pertanyaan mudah-mudahan-jelas adalah mengapa mesin runtime PHP harus mengasumsikan di muka bahwa Anda ingin melacak hal-hal seperti itu, daripada membiarkan Anda melakukannya secara eksplisit, menggunakan kode normal.

IMSoP
sumber
Mengenai kelas dan properti, sayangnya property_exists () tidak berfungsi ketika properti adalah array, misalnya: Kelas {public $ property = array ()}. Melempar kesalahan
Andrew
1
@Andrew Tampaknya bekerja dengan baik untuk saya: 3v4l.org/TnAY5 Ingin memberikan contoh lengkap?
IMSoP
ya sepertinya berfungsi dengan baik, ada yang salah dengan setup saya. Maaf untuk alarm salah :)
Andrew
20

Kadang-kadang saya sedikit tersesat ketika mencoba mencari tahu operasi perbandingan mana yang digunakan dalam situasi tertentu. isset()hanya berlaku untuk nilai yang tidak diinisialisasi atau null secara eksplisit. Melewati / menetapkan null adalah cara yang bagus untuk memastikan perbandingan logis berfungsi seperti yang diharapkan.

Namun, ini agak sulit untuk dipikirkan jadi inilah matriks sederhana yang membandingkan bagaimana nilai yang berbeda akan dievaluasi oleh operasi yang berbeda:

|           | ===null | is_null | isset | empty | if/else | ternary | count>0 |
| -----     | -----   | -----   | ----- | ----- | -----   | -----   | -----   |
| $a;       | true    | true    |       | true  |         |         |         |
| null      | true    | true    |       | true  |         |         |         |
| []        |         |         | true  | true  |         |         |         |
| 0         |         |         | true  | true  |         |         | true    |
| ""        |         |         | true  | true  |         |         | true    |
| 1         |         |         | true  |       | true    | true    | true    |
| -1        |         |         | true  |       | true    | true    | true    |
| " "       |         |         | true  |       | true    | true    | true    |
| "str"     |         |         | true  |       | true    | true    | true    |
| [0,1]     |         |         | true  |       | true    | true    | true    |
| new Class |         |         | true  |       | true    | true    | true    |

Agar sesuai dengan tabel, saya sedikit mengkompresi label:

  • $a; mengacu pada variabel yang dideklarasikan tetapi tidak ditugaskan
  • segala sesuatu di kolom pertama merujuk ke nilai yang diberikan, seperti:
    • $a = null;
    • $a = [];
    • $a = 0;
    • ...
  • kolom merujuk pada operasi perbandingan, seperti:
    • $a === null
    • isset($a)
    • empty($a)
    • $a ? true : false
    • ...

Semua hasil adalah boolean, truedicetak dan falsedihilangkan.

Anda dapat menjalankan tes sendiri, periksa intisari ini:
https://gist.github.com/mfdj/8165967

Mark Fox
sumber
Mungkin di luar cakupan pertanyaan ini, tetapi Anda mungkin ingin menambahkan "0"ke tabel, untuk kelengkapan dan kejelasan emptyoperasi
Rik Schaaf
17

Anda bisa menggunakan bahasa kompak untuk menguji keberadaan variabel nol. Variabel yang tidak ada tidak akan muncul dalam hasil, sementara nilai nol akan ditampilkan.

$x = null;
$y = 'y';

$r = compact('x', 'y', 'z');
print_r($r);

// Output:
// Array ( 
//  [x] => 
//  [y] => y 
// ) 

Dalam hal contoh Anda:

if (compact('v')) {
   // True if $v exists, even when null. 
   // False on var $v; without assignment and when $v does not exist.
}

Tentu saja untuk variabel dalam lingkup global Anda juga dapat menggunakan array_key_exists ().

Btw secara pribadi saya akan menghindari situasi seperti wabah di mana ada perbedaan semantik antara variabel yang tidak ada dan variabel yang memiliki nilai nol. PHP dan sebagian besar bahasa lainnya hanya tidak berpikir ada.

Matijs
sumber
3
PHP tidak, tapi saya tidak akan mengatakan sebagian besar bahasa lain tidak. Sebagian besar bahasa apa pun yang menyatakan variabel akan melempar kesalahan jika variabel belum dideklarasikan, tetapi Anda dapat mengaturnya NULL. Semantik, NULLharus berarti "tidak ada sumber daya," tetapi tidak mendefinisikan variabel adalah kesalahan programmer.
M Miller
1
@ MMiller Tentu, tetapi menulis kode yang mengikuti satu jalur dalam kasus "tidak ada sumber daya" dan jalur yang berbeda dalam kasus "kesalahan programmer" cukup tidak masuk akal. Jika Anda ingin mendeteksi variabel yang tidak dideklarasikan selama debugging, gunakan alat analisis statis, seperti Anda akan menemukan potensi kesalahan dalam bahasa apa pun.
IMSoP
@ MMiller, Keren, bagaimana Anda bahkan memikirkan hal ini.
Pacerier
1
@ MMiller Tapi itu tidak berfungsi sebagai bantahan, karena pernyataan dalam jawaban secara eksplisit tentang "variabel tidak ada", dan contoh balasan Anda adalah tentang properti objek / kunci hash tidak ada . Perbedaan antara kasus-kasus ini bukan hanya kebetulan.
IMSoP
1
@ MMiller - memang itu contoh yang lebih baik. Namun, setelah 20+ tahun pemrograman dalam bahasa yang ketat, situasi di mana saya membutuhkan perbedaan antara undefineddan nullsangat jarang sehingga saya tidak ketinggalan. IMHO, penggunaan utama undefinedadalah "kesalahan programmer dalam bahasa yang tidak ketat". Dalam bahasa yang ketat, jika saya memerlukan kondisi berbeda client did not state a value, maka saya menyatakan nilai yang sesuai dengan situasi, dan mengujinya. Kasus terburuk, harus menambahkan variabel flag terpisah. Tetapi melakukan itu jarang lebih baik daripada harus SELALU mengatasi DUA kondisi tidak-nilai yang berbeda !!
ToolmakerSteve
15

Menjelaskan NULL, berpikir logis

Saya kira jawaban yang jelas untuk semua ini adalah ... Jangan menginisialisasi variabel Anda sebagai NULL, initalise mereka sebagai sesuatu yang relevan dengan apa yang mereka inginkan.

Perlakukan NULL dengan benar

NULL harus diperlakukan sebagai "nilai tidak ada", yang merupakan arti dari NULL. Variabel tidak dapat digolongkan sebagai yang ada ke PHP karena belum diberi tahu jenis entitas apa yang dicoba untuk dibuat. Mungkin juga tidak ada, jadi PHP hanya mengatakan "Baik, tidak karena tidak ada gunanya dan NULL adalah cara saya mengatakan ini".

Sebuah argumen

Mari kita berdebat sekarang. "Tapi NULL seperti mengatakan 0 atau SALAH atau ''.

Salah, 0-FALSE- '' semuanya masih digolongkan sebagai nilai kosong, tetapi ADA ditentukan sebagai beberapa jenis nilai atau jawaban yang ditentukan sebelumnya untuk pertanyaan. FALSE adalah jawaban untuk ya atau tidak, '' adalah jawaban untuk judul yang dikirimkan seseorang, dan 0 adalah jawaban untuk kuantitas atau waktu dll. Mereka DILAKUKAN sebagai beberapa jenis jawaban / hasil yang membuat mereka valid sebagai yang ditetapkan.

NULL tidak ada jawaban apa pun, itu tidak memberi tahu kami ya atau tidak dan itu tidak memberi tahu kami waktu dan tidak memberi tahu kami string kosong diterima. Itulah logika dasar dalam memahami NULL.

Ringkasan

Ini bukan tentang membuat fungsi aneh untuk mengatasi masalah, itu hanya mengubah cara otak Anda memandang NULL. Jika NULL, anggap itu tidak disetel sebagai apa pun. Jika Anda menentukan variabel sebelumnya, tentukan sebelumnya sebagai 0, SALAH atau "" tergantung pada jenis penggunaan yang Anda inginkan.

Jangan ragu untuk mengutip ini. Ini keluar dari kepala logis saya :)

greatbigmassive
sumber
5
Jawaban yang bagus Sering kali saya melihat orang mengomel tentang bagaimana mereka membenci fitur bahasa ini atau itu. Tetapi mereka tampaknya berasumsi bahwa "jika tidak melakukannya dengan cara SAYA, maka itu rusak." Ya, ada keputusan desain yang buruk. Tetapi ada juga pengembang yang sangat tertutup!
curtisdf
23
ADA perbedaan BESAR antara variabel tidak disetel dan variabel === null. Satu tidak ada, yang lain memiliki nilai nol. Argumen yang nol berarti tidak ada nilai sama sekali tidak benar. Null ADALAH NILAI dari tipe null. Ini nilai yang benar-benar valid dan tidak ada alasan bagi php untuk memperlakukannya sebagai nilai yang tidak ada, yang sayangnya tidak. Ini akan baik-baik saja, jika variabel yang tidak ada adalah nol dan setiap variabel yang ada tidak-nol dan menetapkan nol ke dalam variabel akan menghapusnya. Tetapi ada banyak situasi, di mana fungsi mengembalikan nol sebagai nilai aktual. Lalu kita kacau, karena tidak ada cara berdarah untuk mengujinya.
enrey
2
Saya tahu kita "tidak seharusnya" memeriksa keberadaan variabel di php, sial, bahkan tidak ada cara nyata untuk memeriksanya. Saya tidak akan menulis kode yang bergantung padanya, karena tidak mungkin di php. Itu batasan php. Jelas ada perbedaan antara variabel non-set dan null, namun php tidak memberikan cara untuk membedakannya. Namun banyak fungsi meta tergantung padanya internaly: membaca var yang tidak ada menghasilkan pemberitahuan, isset($a['x'])akan memberi tahu Anda salah jika xnull, namun itu akan muncul di count($a).. compactakan bekerja pada semua variabel yang ditetapkan, termasuk nulls, dan sebagainya.
enrey
3
Jawaban ini cacat dalam satu cara utama: dalam pemrograman OO, null adalah pilihan logis untuk berarti "tidak ada objek". Sebagai contoh, dalam keadaan tanpa pengecualian ketika suatu fungsi dapat mengembalikan suatu objek atau tidak ada objek, null adalah pilihan yang jelas. Secara teknis dalam PHP, false atau nilai lain yang dianggap false dalam konteks boolean dapat digunakan, tetapi kemudian Anda kehilangan beberapa kemurnian semantik. Dengan demikian, null adalah nilai yang masuk akal untuk menginisialisasi variabel itu harus memegang sebuah benda akhirnya, karena ini relevan dengan apa itu dimaksudkan untuk menjadi.
chazomaticus
3
Selama PHP melempar kesalahan untuk variabel yang tidak ditentukan, tetapi tidak untuk nol, maka ada perbedaan. Jika null dan undefined benar-benar konsep yang sama, maka PHP harus mengasumsikan variabel default tidak terdefinisi / tidak dideklarasikan menjadi nol dan tidak pernah melempar kesalahan, tetapi tidak ada yang mau itu karena itu adalah mimpi buruk pengembangan. Null dan tidak terdefinisi mungkin tidak benar-benar berbeda dalam konteks semantik nilai, tetapi mereka sangat berbeda dalam hal penulisan kode yang jelas dan dapat di-debuggable.
Chris Middleton
9

Properti objek dapat diperiksa keberadaannya oleh property_exists

Contoh dari unit test:

function testPropertiesExist()
{
    $sl =& $this->system_log;
    $props = array('log_id',
                   'type',
                   'message',
                   'username',
                   'ip_address',
                   'date_added');

    foreach($props as $prop) {
        $this->assertTrue(property_exists($sl, $prop),
                           "Property <{$prop}> exists");
    }
}

sumber
4

Sebagai tambahan untuk diskusi greatbigmassive tentang apa arti NULL , pertimbangkan apa arti sebenarnya "keberadaan suatu variabel".

Dalam banyak bahasa, Anda harus mendeklarasikan secara eksplisit setiap variabel sebelum menggunakannya ; ini mungkin menentukan jenisnya, tetapi yang lebih penting ia menyatakan cakupannya . Variabel "ada" di mana-mana dalam cakupannya, dan tidak ada di luarnya - baik itu fungsi keseluruhan, atau "blok" tunggal.

Dalam ruang lingkupnya, sebuah variabel memberikan makna pada label yang telah Anda, sang programmer, pilih. Di luar cakupannya, label itu tidak ada artinya (apakah Anda menggunakan label yang sama dalam cakupan yang berbeda pada dasarnya tidak relevan).

Dalam PHP, variabel tidak perlu dideklarasikan - mereka menjadi hidup segera setelah Anda membutuhkannya. Saat Anda menulis ke variabel untuk pertama kalinya, PHP mengalokasikan entri dalam memori untuk variabel itu. Jika Anda membaca dari variabel yang saat ini tidak memiliki entri, PHP menganggap variabel itu memiliki nilai NULL.

Namun, detektor kualitas kode otomatis umumnya akan memperingatkan Anda jika Anda menggunakan variabel tanpa "menginisialisasi" terlebih dahulu. Pertama, ini membantu mendeteksi kesalahan ketik, seperti menetapkan $thingIdtetapi membaca dari $thing_id; tetapi kedua, itu memaksa Anda untuk mempertimbangkan ruang lingkup di mana variabel itu memiliki makna, seperti halnya deklarasi.

Kode apa pun yang peduli apakah suatu variabel "ada" adalah bagian dari ruang lingkup variabel itu - apakah itu telah diinisialisasi atau tidak, Anda sebagai programmer telah memberi makna label pada titik kode tersebut. Karena Anda menggunakannya, itu harus dalam arti "ada", dan jika ada, itu harus memiliki nilai implisit; dalam PHP, nilai implisitnya adalah null.

Karena cara kerja PHP, dimungkinkan untuk menulis kode yang memperlakukan namespace variabel yang ada bukan sebagai ruang lingkup label yang telah Anda berikan makna, tetapi sebagai semacam penyimpanan nilai kunci. Anda dapat, misalnya, menjalankan kode seperti ini: $var = $_GET['var_name']; $$var = $_GET['var_value'];. Hanya karena Anda bisa, bukan berarti itu ide yang bagus.

Ternyata, PHP memiliki cara yang jauh lebih baik untuk mewakili penyimpanan nilai kunci, yang disebut array asosiatif. Dan meskipun nilai-nilai array dapat diperlakukan seperti variabel, Anda juga dapat melakukan operasi pada array secara keseluruhan. Jika Anda memiliki array asosiatif, Anda dapat menguji apakah itu berisi kunci menggunakan array_key_exists().

Anda juga dapat menggunakan objek dengan cara yang sama, mengatur properti secara dinamis, dalam hal ini Anda dapat menggunakan property_exists()dengan cara yang persis sama. Tentu saja, jika Anda mendefinisikan kelas, Anda dapat mendeklarasikan sifat-sifat yang telah - Anda bahkan dapat memilih antara public, private, dan protectedruang lingkup.

Meskipun ada perbedaan teknis antara variabel (sebagai lawan kunci array, atau properti objek) yang belum diinisialisasi (atau yang telah secara eksplisit unset()) dan yang nilainya null, kode apa pun yang menganggap perbedaan itu bermakna menggunakan variabel dengan cara yang tidak dimaksudkan untuk digunakan.

IMSoP
sumber
1
Poin yang sangat bagus, meskipun bukan jawaban yang tepat untuk pertanyaan itu.
chazomaticus
1
Untuk pertanyaan eksplisit "Bagaimana kita seharusnya memeriksa keberadaan variabel dalam PHP?" jawaban saya adalah "Anda tidak, dan inilah sebabnya". Baik jawaban ini maupun greatbigmassive juga menjawab pertanyaan tersirat "mengapa isset()berperilaku seperti itu?".
IMSoP
"Jika Anda membaca dari variabel yang saat ini tidak memiliki entri, PHP menganggap variabel itu memiliki nilai NULL." Ini salah. Variabel tidak terdefinisi hanya tidak terdefinisi. Mungkin mengembalikan nol ketika Anda mencoba mengaksesnya, tetapi itu tidak relevan.
Hugo Zink
@HugoZink Tidak relevan dengan apa? Setiap tes yang Anda lakukan terhadap nilai variabel yang tidak terdefinisi akan memberi tahu Anda bahwa nilainya null. Apakah nilai itu ada sebelum Anda melihatnya adalah pertanyaan bagi para filsuf, tetapi sejauh menyangkut perilaku yang dapat diamati, nilainya secara konsisten null.
IMSoP
3

issetmemeriksa apakah variabel diatur dan, jika demikian, apakah nilainya bukan NULL. Bagian terakhir adalah (menurut saya) tidak dalam ruang lingkup fungsi ini. Tidak ada solusi yang layak untuk menentukan apakah suatu variabel adalah NULL karena tidak disetel atau karena secara eksplisit diatur ke NULL .

Berikut adalah satu solusi yang mungkin:

$e1 = error_get_last();
$isNULL = is_null(@$x);
$e2 = error_get_last();
$isNOTSET = $e1 != $e2;
echo sprintf("isNOTSET: %d, isNULL: %d", $isNOTSET, $isNULL);

// Sample output:
// when $x is not set: isNOTSET: 1, isNULL: 1
// when $x = NULL:     isNOTSET: 0, isNULL: 1
// when $x = false:    isNOTSET: 0, isNULL: 0

Solusi lain adalah untuk menyelidiki output dari get_defined_vars():

$vars = get_defined_vars();
$isNOTSET = !array_key_exists("x", $vars);
$isNULL = $isNOTSET ? true : is_null($x);
echo sprintf("isNOTSET: %d, isNULL: %d", $isNOTSET, $isNULL);

// Sample output:
// when $x is not set: isNOTSET: 1, isNULL: 1
// when $x = NULL:     isNOTSET: 0, isNULL: 1
// when $x = false:    isNOTSET: 0, isNULL: 0
Salman A
sumber
2

Saya tidak setuju dengan alasan Anda tentang NULL , dan mengatakan bahwa Anda perlu mengubah pola pikir Anda tentang NULL adalah aneh.

Saya pikir isset () tidak dirancang dengan benar, isset () harus memberi tahu Anda jika variabel telah ditetapkan dan tidak boleh berkaitan dengan nilai aktual dari variabel.

Bagaimana jika Anda memeriksa nilai yang dikembalikan dari database dan salah satu kolom memiliki nilai NULL, Anda masih ingin tahu apakah itu ada bahkan jika nilainya NULL ... nggak, jangan percaya isset () di sini.

juga

$a = array ('test' => 1, 'hello' => NULL);

var_dump(isset($a['test']));   // TRUE
var_dump(isset($a['foo']));    // FALSE
var_dump(isset($a['hello']));  // FALSE

isset () seharusnya dirancang untuk bekerja seperti ini:

if(isset($var) && $var===NULL){....

dengan cara ini kita menyerahkannya kepada programmer untuk memeriksa jenis dan tidak menyerahkannya ke isset () untuk menganggapnya tidak ada karena nilainya NULL - desainnya yang bodoh

Christof Coetzee
sumber
Contoh Anda tidak memeriksa keberadaan variabel, tetapi kunci array. Solusi untuk yang ada, dalam bentuk array_key_exists. Anda seharusnya tidak pernah berada dalam situasi di mana Anda tidak tahu saat runtime jika variabel aktual ada.
IMSoP
@chazomaticus Ya, Anda seharusnya tidak pernah berada dalam situasi di mana register_globals dihidupkan, jadi saya mendukung pernyataan itu.
IMSoP
Oh saya setuju. Namun, tidak semua orang dapat mengontrol di mana kode mereka digunakan. Sangat berguna untuk memiliki informasi untuk setiap situasi, apakah itu bagaimana "seharusnya" menjadi atau tidak.
chazomaticus
@chazomaticus Jika masalah Anda adalah register_globals, maka jawaban Anda tidak berubah menjadi isset(). Manual PHP menyebutkan "ini umumnya merupakan praktik pemrograman yang baik untuk menginisialisasi variabel terlebih dahulu", yang diselesaikan register_globalspada saat desain daripada pada saat dijalankan. Ada juga entri FAQ yang memberikan unregister_globals()fungsi untuk menghadapinya saat run-time.
IMSoP
2

Saya akan menambahkan dua sen cepat untuk ini. Salah satu alasan masalah ini membingungkan adalah karena skenario ini tampaknya mengembalikan hasil yang sama dengan pelaporan kesalahan tidak secara penuh:

$a = null;
var_dump($a); // NULL
var_dump($b); // NULL

Anda dapat mengasumsikan dari hasil ini bahwa perbedaan antara $a = nulldan tidak mendefinisikan $bsama sekali bukanlah apa-apa.

Kesalahan engkol melaporkan:

NULL

Notice: Undefined variable: b in xxx on line n
NULL

Catatan: itu melempar kesalahan variabel yang tidak ditentukan, tetapi nilai output var_dumpmasih NULL.

PHP jelas memiliki kemampuan internal untuk membedakan antara variabel nol dan variabel tidak terdefinisi. Sepertinya saya harus ada fungsi bawaan untuk memeriksa ini.

Saya pikir jawaban yang diterima baik untuk sebagian besar, tetapi jika saya akan mengimplementasikannya saya akan menulis pembungkus untuk itu. Seperti yang disebutkan sebelumnya dalam jawaban ini , saya harus setuju bahwa saya belum benar-benar menghadapi situasi di mana ini menjadi masalah. Saya hampir selalu berakhir dalam skenario di mana variabel saya ditetapkan dan ditentukan, atau tidak (tidak terdefinisi, tidak disetel, nol, kosong, dll.). Bukan untuk mengatakan bahwa situasi seperti ini tidak akan terjadi di masa depan, tetapi karena tampaknya ini adalah masalah yang cukup unik, saya tidak terkejut bahwa para pengembang PHP tidak mau repot-repot memasukkannya.

Robbie Averill
sumber
Peringatan pada variabel tidak terdefinisi adalah petunjuk bagi programmer bahwa mereka telah melakukan sesuatu yang salah dalam kode. Di luar debugging (yang ada alat di luar bahasa), seharusnya tidak pernah ada kebutuhan untuk program untuk mendeteksi keadaan seperti itu, karena programmer harus selalu tahu variabel apa yang mereka nyatakan.
IMSoP
1

Jika saya menjalankan yang berikut ini:

echo '<?php echo $foo; ?>' | php

Saya mendapatkan kesalahan:

PHP Notice:  Undefined variable: foo in /home/altern8/- on line 1

Jika saya menjalankan yang berikut ini:

echo '<?php if ( isset($foo) ) { echo $foo; } ?>' | php

Saya tidak mendapatkan kesalahan.

Jika saya memiliki variabel yang harus ditetapkan, saya biasanya melakukan sesuatu seperti berikut ini.

$foo = isset($foo) ? $foo : null;

atau

if ( ! isset($foo) ) $foo = null;

Dengan begitu, nanti dalam skrip, saya dapat menggunakan $ foo dengan aman dan tahu bahwa "diset", dan defaultnya adalah nol. Nanti aku bisaif ( is_null($foo) ) { /* ... */ } jika saya perlu dan tahu pasti bahwa variabel itu ada, bahkan jika itu nol.

Dokumentasi penerbit lengkap membaca sedikit lebih dari apa yang awalnya ditempel. Ya, itu mengembalikan false untuk variabel yang sebelumnya ditetapkan tetapi sekarang nol, tetapi juga mengembalikan false jika variabel belum disetel (pernah) dan untuk setiap variabel yang telah ditandai sebagai tidak disetel. Ini juga mencatat bahwa byte NULL ("\ 0") tidak dianggap nol dan akan mengembalikan true.

Tentukan apakah suatu variabel diatur.

Jika variabel tidak disetel dengan tidak disetel (), itu tidak akan lagi ditetapkan. isset () akan mengembalikan FALSE jika menguji variabel yang telah disetel ke NULL. Perhatikan juga bahwa byte NULL ("\ 0") tidak setara dengan konstanta PHP NULL.

Beau Simensen
sumber
Dia mengambil dokumen dari tautan itu. Baca kalimat pertama, paragraf kedua dari bagian deskripsi pada tautan yang Anda berikan. Ini persis seperti yang ia kutip di atas.
Zoredache
Ini bukan praktik yang buruk untuk skrip sederhana, tetapi dalam proyek yang kompleks (misalnya OO besar), itu menjadi tidak layak. Juga, seperti yang saya katakan di atas, is_null () mengembalikan TRUE untuk variabel yang tidak disetel, jadi benar-benar tidak ada alasan untuk melakukan apa yang Anda katakan kecuali untuk menghindari peringatan PHP.
chazomaticus
1
Untuk proyek "OO besar" yang dirancang dengan baik, mengapa ini menjadi masalah? Mengapa Anda pernah memiliki $ foo di badan metode yang mungkin belum ditetapkan sebelum penggunaan pertama?
Beau Simensen
1

Coba gunakan

unset($v)

Tampaknya satu-satunya waktu variabel tidak diset adalah ketika secara khusus tidak disetel ($ v). Sepertinya makna 'keberadaan' Anda berbeda dari definisi PHP. NULL pasti ada, itu NULL.

Joe Phillips
sumber
Saya tidak yakin apa yang Anda maksud. Jika Anda memiliki larik, dengan satu elemen 'a', Anda tidak harus membatalkan set () elemen 'b' untuk elemen 'b' tidak ada di PHP, itu tidak ada. Hal yang sama dengan misalnya variabel global, yang dapat Anda anggap sebagai elemen dari array $ GLOBALS.
chazomaticus
1
Tapi saya setuju bahwa variabel dengan nilai NULL memang ada.
chazomaticus
0

Saya harus mengatakan dalam semua tahun pemrograman PHP, saya tidak pernah menemui masalah dengan isset()mengembalikan false pada variabel nol. OTOH, saya mengalami masalah dengan isset()gagal pada entri array nol - tetapi array_key_exists()berfungsi dengan benar dalam kasus itu.

Untuk beberapa perbandingan, Ikon secara eksplisit mendefinisikan variabel yang tidak digunakan sebagai pengembalian &nullsehingga Anda menggunakan tes is-null di Ikon untuk juga memeriksa variabel yang tidak disetel. Ini memang membuat segalanya lebih mudah. Di sisi lain, Visual BASIC memiliki beberapa status untuk variabel yang tidak memiliki nilai (Null, Kosong, Tidak ada, ...), dan Anda sering harus memeriksa lebih dari satu. Ini dikenal sebagai sumber bug.

ahli statika
sumber
0

Menurut Manual PHP untuk fungsi kosong (), "Tentukan apakah variabel dianggap kosong. Variabel dianggap kosong JIKA TIDAK ADA atau jika nilainya sama dengan SALAH. Kosong () tidak menghasilkan peringatan jika variabel tidak ada. " (Penekanan saya.) Itu berarti fungsi kosong () harus memenuhi syarat sebagai "cara terbaik untuk menguji keberadaan variabel dalam PHP", per judul Pertanyaan.

Namun, ini tidak cukup baik, karena fungsi kosong () dapat tertipu oleh variabel yang ada dan disetel ke NULL.

Saya menginterupsi jawaban saya sebelumnya untuk menyajikan sesuatu yang lebih baik, karena itu kurang rumit daripada jawaban asli saya (yang mengikuti gangguan ini, untuk membandingkan).

  function undef($dnc) //do not care what we receive
  { $inf=ob_get_contents();             //get the content of the buffer
    ob_end_clean();                     //stop buffering outputs, and empty the buffer
    if($inf>"")                         //if test associated with the call to this function had an output
    { if(false!==strpos($inf, "Undef"); //if the word "Undefined" was part of the output
        return true;                    //tested variable is undefined
    }
    return false;                       //tested variable is not undefined
  }

Dua baris kode sederhana dapat menggunakan fungsi di atas untuk mengungkapkan jika suatu variabel tidak terdefinisi:

  ob_start();                           //pass all output messages (including errors) to a buffer
  if(undef($testvar===null))            //in this case the variable being tested is $testvar

Anda dapat mengikuti dua baris tersebut dengan apa pun yang sesuai, seperti contoh ini:

    echo("variable is undefined");
  else
    echo("variable exists, holding some value");

Saya ingin meletakkan panggilan ke ob_start () dan ($ testvar === null) di dalam fungsi, dan hanya meneruskan variabel ke fungsi, tetapi tidak berhasil. Bahkan jika Anda mencoba menggunakan "lulus dengan referensi" dari variabel ke fungsi, variabel BECOMES didefinisikan, dan kemudian fungsi tidak pernah dapat mendeteksi bahwa itu sebelumnya telah terdefinisi. Apa yang disajikan di sini adalah kompromi antara apa yang ingin saya lakukan, dan apa yang sebenarnya berhasil.

Penjelasan sebelumnya menyiratkan bahwa ada cara lain untuk selalu menghindari pesan kesalahan "variabel tidak terdefinisi". (Asumsinya di sini adalah, mencegah pesan seperti itu adalah mengapa Anda ingin menguji untuk melihat apakah suatu variabel tidak terdefinisi.)

   function inst(&$v) { return; }  //receive any variable passed by reference; instantiates the undefined

Panggil saja fungsi itu sebelum melakukan sesuatu ke $ testvar Anda:

   inst($testvar);                //The function doesn't affect any value of any already-existing variable

Nilai variabel yang baru-instantiated diatur ke nol, tentu saja!

(Gangguan berakhir)

Jadi, setelah beberapa belajar dan bereksperimen, berikut adalah sesuatu yang dijamin berhasil:

 function myHndlr($en, $es, $ef, $el)
 { global $er;
   $er = (substr($es, 0, 18) == "Undefined variable");
   return;
 }

 $er = false;
 if(empty($testvar))
 { set_error_handler("myHndlr");
   ($testvar === null);
   restore_error_handler();
 }
 if($er)  // will be 1 (true) if the tested variable was not defined.
 { ; //do whatever you think is appropriate to the undefined variable
 }

Penjelasan: Variabel $ er diinisialisasi ke nilai default "no error". "Fungsi penangan" didefinisikan. Jika $ testvar (variabel yang kita ingin tahu apakah tidak terdefinisi) melewati tes fungsi preliminary empty (), maka kita melakukan tes yang lebih menyeluruh. Kami memanggil fungsi set_error_handler () untuk menggunakan fungsi handler yang didefinisikan sebelumnya. Kemudian kami melakukan perbandingan identitas sederhana yang melibatkan $ testvar, YANG JIKA TIDAK AKAN MEMENUHI KESALAHAN. Fungsi handler menangkap kesalahan dan secara khusus menguji untuk melihat apakah alasan kesalahan adalah fakta bahwa variabel tidak terdefinisi. Hasilnya ditempatkan dalam variabel eror-informasi $ er, yang nantinya bisa kita uji untuk melakukan apa pun yang kita inginkan sebagai hasil dari mengetahui dengan pasti apakah $ testvar didefinisikan atau tidak. Karena kita hanya memerlukan fungsi handler untuk tujuan terbatas ini, kami mengembalikan fungsi penanganan kesalahan yang asli. Fungsi "myHndlr" hanya perlu dinyatakan satu kali; kode lain dapat disalin ke tempat apa pun yang sesuai, untuk $ testvar atau variabel lain yang ingin kami uji dengan cara ini.

vernonner3voltazim
sumber
1
Jika tujuannya adalah untuk menghindari peringatan bahwa variabel Anda belum dideklarasikan, maka solusinya adalah memperbaiki kode Anda untuk menyatakannya dengan benar. instFungsi Anda pada dasarnya seperti @operator penekan-kesalahan: "Saya tahu saya melakukan sesuatu yang salah di sini, tetapi saya hanya ingin pesan itu hilang, tanpa benar-benar mengubah operasi kode saya dengan cara apa pun".
IMSoP
Metode deteksi, di lain pihak, sangat cerdik, tetapi saya masih yakin bahwa Anda seharusnya tidak pernah menggunakannya selain untuk menggemakan pesan peringatan yang mereka tangkap. (Anda mungkin harus mengklarifikasi bahwa versi buffering output Anda memerlukan error_reporting set high dan display_errors untuk dihidupkan.)
IMSoP
0

Saya pikir satu-satunya solusi lengkap untuk melaporkan pemberitahuan dengan

error_reporting(E_ALL); // Enables E_NOTICE

Tetapi Anda harus memperbaiki semua pemberitahuan yang dihasilkan oleh variabel yang tidak terdefinisi, konstanta, kunci array, dan properti kelas. Setelah Anda selesai melakukannya, Anda tidak perlu khawatir tentang perbedaan antara variabel nol dan tidak dideklarasikan, dan ambiguitas menghilang.

Mengaktifkan pelaporan pemberitahuan mungkin bukan alternatif yang baik dalam semua situasi, tetapi ada alasan bagus untuk mengaktifkannya:

Mengapa saya harus memperbaiki kesalahan E_NOTICE?

Dalam kasus saya lebih dari setahun bekerja di proyect tanpa itu, tetapi digunakan untuk berhati-hati dalam mendeklarasikan variabel, jadi itu cepat untuk transisi.

mikl
sumber
0

Satu-satunya cara untuk mengetahui apakah suatu variabel didefinisikan dalam lingkup saat ini ( $GLOBALStidak dapat dipercaya) adalah array_key_exists( 'var_name', get_defined_vars() ).

Kostas Podias
sumber
1
Saya pikir itu yang dikatakan banyak orang sebelumnya, atau saya salah?
Stephan Vierkant
-1

Saya lebih suka menggunakan tidak kosong sebagai metode terbaik untuk memeriksa keberadaan variabel yang a) ada, dan b) bukan nol.

if (!empty($variable)) do_something();
Hal
sumber
2
empty()tidak memeriksa apakah variabelnya nol, ia memeriksa apakah itu false-y, misal bukan salah satu dari ""(string kosong), 0(0 sebagai bilangan bulat), 0.0(0 sebagai float), "0"(0 sebagai string) NULL,, FALSE, array()(array kosong) dan $var;(variabel dideklarasikan, tetapi tanpa nilai). Katakanlah Anda memiliki bidang radio yang diperlukan dalam bentuk dengan dua input dengan nilai 0dan 1. Jika Anda menggunakan empty()untuk validasi dan pengguna memilih 0satu, Anda secara tidak sengaja akan menghapus "bidang yang diperlukan tidak boleh kosong". Lihat manual php.net/manual/en/function.empty.php
Halil Özgür