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 $v
tidak disetel) tetapi is_null()
memiliki masalah yang mirip dengan isset()
: ia mengembalikan TRUE
variabel 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 NULL
nilai. 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 UPDATE
pernyataan SQL , di mana kunci array adalah kolom tabel, dan nilai array adalah nilai yang akan diterapkan ke setiap kolom. Setiap kolom tabel dapat menyimpan NULL
nilai, yang ditandai dengan meneruskan NULL
nilai 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
.)
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, bukannull
.Jawaban:
Jika variabel yang Anda periksa akan berada dalam lingkup global yang dapat Anda lakukan:
sumber
$defined_vars = get_defined_vars();
dan kemudian menguji melaluiarray_key_exists('v', $defined_vars);
.isset($foo[$bar])
menjadiarray_key_exists($bar, $foo)
property_exists
tampaknya menjanjikan, kecuali untuk ini:> Fungsi property_exists () tidak dapat mendeteksi properti yang dapat diakses secara ajaib menggunakan metode __get magic.Mencoba memberikan ikhtisar dari berbagai diskusi dan jawaban:
Tidak ada jawaban tunggal untuk pertanyaan yang dapat menggantikan semua cara yang
isset
dapat 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 mengapaisset
reaksi terhadapnull
perilaku logis.Kasus penggunaan nyata (dengan solusi)
1. Array keys
Array dapat diperlakukan seperti kumpulan variabel, dengan
unset
danisset
memperlakukan mereka seolah-olah mereka. Namun, karena mereka dapat diulang, dihitung, dll, nilai yang hilang tidak sama dengan nilai yang nilainyanull
.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 penanganannull
nilai.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
, atauprivate
).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, disebut
property_exists
,.Kasus penggunaan yang tidak dapat dibenarkan, dengan diskusi
3.
register_globals
, dan polusi lain dari namespace globalThe
register_globals
fitur 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, menggunakanglobal
kata kunci, atau$GLOBALS
array.Pertama,
register_globals
itu sendiri tidak mungkin menghasilkannull
variabel, karena nilai GET, POST, dan cookie akan selalu berupa string (dengan''
masih kembalitrue
dariisset
), dan variabel dalam sesi harus sepenuhnya di bawah kendali programmer.Kedua, pencemaran suatu variabel dengan nilai
null
hanya masalah jika ini berlebihan menulis beberapa inisialisasi sebelumnya. "Over-writing" suatu variabel yang tidak diinisialisasi dengannull
hanya 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_vars
dancompact
Beberapa fungsi yang jarang digunakan dalam PHP, seperti
get_defined_vars
dancompact
, 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.
isset
jauh 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
htmlspecialchars
sehingga 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:
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$a
dan$b
dalam kode ini akan berakhir sebagai integer42
:(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:
Jika
some_function
bisa kembalinull
, ada kemungkinanecho
tidak akan tercapai walaupunsome_test
dikembalikantrue
. Tujuan programmer adalah untuk mendeteksi kapan$result
tidak pernah diatur, tetapi PHP tidak mengizinkan mereka untuk melakukannya.Namun, ada masalah lain dengan pendekatan ini, yang menjadi jelas jika Anda menambahkan loop luar:
Karena
$result
tidak 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
$result
ke "nilai terminal" yangsome_function
tidak pernah bisa kembali; jika ininull
, maka sisa kode akan berfungsi dengan baik. Jika tidak ada kandidat alami untuk nilai terminal karenasome_function
memiliki 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_null
konstantaPHP 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 dipaksanull
, 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 bahwasome_function
tidak 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$result
yang tidak dapat diteruskan, dan hanya dapat terdeteksi oleh fungsi bawaan tertentu.Percobaan dua pemikiran: penugasan tugas
Cara lain untuk berpikir tentang apa yang terakhir
if
ditanyakan 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, daripadaisset
Anda mungkin menyebutnyahas_been_assigned_to
, dan bukanunset
,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_count
danreset_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_null
konstanta, 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.
sumber
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:
Agar sesuai dengan tabel, saya sedikit mengkompresi label:
$a;
mengacu pada variabel yang dideklarasikan tetapi tidak ditugaskan$a = null;
$a = [];
$a = 0;
$a === null
isset($a)
empty($a)
$a ? true : false
Semua hasil adalah boolean,
true
dicetak danfalse
dihilangkan.Anda dapat menjalankan tes sendiri, periksa intisari ini:
https://gist.github.com/mfdj/8165967
sumber
"0"
ke tabel, untuk kelengkapan dan kejelasanempty
operasiAnda bisa menggunakan bahasa kompak untuk menguji keberadaan variabel nol. Variabel yang tidak ada tidak akan muncul dalam hasil, sementara nilai nol akan ditampilkan.
Dalam hal contoh Anda:
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.
sumber
NULL
. Semantik,NULL
harus berarti "tidak ada sumber daya," tetapi tidak mendefinisikan variabel adalah kesalahan programmer.undefined
dannull
sangat jarang sehingga saya tidak ketinggalan. IMHO, penggunaan utamaundefined
adalah "kesalahan programmer dalam bahasa yang tidak ketat". Dalam bahasa yang ketat, jika saya memerlukan kondisi berbedaclient 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 !!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 :)
sumber
isset($a['x'])
akan memberi tahu Anda salah jikax
null, namun itu akan muncul dicount($a)
..compact
akan bekerja pada semua variabel yang ditetapkan, termasuknulls
, dan sebagainya.Properti objek dapat diperiksa keberadaannya oleh property_exists
Contoh dari unit test:
sumber
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
$thingId
tetapi 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 antarapublic
,private
, danprotected
ruang 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 nilainyanull
, kode apa pun yang menganggap perbedaan itu bermakna menggunakan variabel dengan cara yang tidak dimaksudkan untuk digunakan.sumber
isset()
berperilaku seperti itu?".null
. Apakah nilai itu ada sebelum Anda melihatnya adalah pertanyaan bagi para filsuf, tetapi sejauh menyangkut perilaku yang dapat diamati, nilainya secara konsistennull
.isset
memeriksa 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:
Solusi lain adalah untuk menyelidiki output dari
get_defined_vars()
:sumber
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
isset () seharusnya dirancang untuk bekerja seperti ini:
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
sumber
array_key_exists
. Anda seharusnya tidak pernah berada dalam situasi di mana Anda tidak tahu saat runtime jika variabel aktual ada.register_globals
, maka jawaban Anda tidak berubah menjadiisset()
. Manual PHP menyebutkan "ini umumnya merupakan praktik pemrograman yang baik untuk menginisialisasi variabel terlebih dahulu", yang diselesaikanregister_globals
pada saat desain daripada pada saat dijalankan. Ada juga entri FAQ yang memberikanunregister_globals()
fungsi untuk menghadapinya saat run-time.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:
Anda dapat mengasumsikan dari hasil ini bahwa perbedaan antara
$a = null
dan tidak mendefinisikan$b
sama sekali bukanlah apa-apa.Kesalahan engkol melaporkan:
Catatan: itu melempar kesalahan variabel yang tidak ditentukan, tetapi nilai output
var_dump
masihNULL
.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.
sumber
Jika saya menjalankan yang berikut ini:
Saya mendapatkan kesalahan:
Jika saya menjalankan yang berikut ini:
Saya tidak mendapatkan kesalahan.
Jika saya memiliki variabel yang harus ditetapkan, saya biasanya melakukan sesuatu seperti berikut ini.
atau
Dengan begitu, nanti dalam skrip, saya dapat menggunakan $ foo dengan aman dan tahu bahwa "diset", dan defaultnya adalah nol. Nanti aku bisa
if ( 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.
sumber
Coba gunakan
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.
sumber
Saya harus mengatakan dalam semua tahun pemrograman PHP, saya tidak pernah menemui masalah dengan
isset()
mengembalikan false pada variabel nol. OTOH, saya mengalami masalah denganisset()
gagal pada entri array nol - tetapiarray_key_exists()
berfungsi dengan benar dalam kasus itu.Untuk beberapa perbandingan, Ikon secara eksplisit mendefinisikan variabel yang tidak digunakan sebagai pengembalian
&null
sehingga 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.sumber
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).
Dua baris kode sederhana dapat menggunakan fungsi di atas untuk mengungkapkan jika suatu variabel tidak terdefinisi:
Anda dapat mengikuti dua baris tersebut dengan apa pun yang sesuai, seperti contoh ini:
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.)
Panggil saja fungsi itu sebelum melakukan sesuatu ke $ testvar Anda:
Nilai variabel yang baru-instantiated diatur ke nol, tentu saja!
(Gangguan berakhir)
Jadi, setelah beberapa belajar dan bereksperimen, berikut adalah sesuatu yang dijamin berhasil:
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.
sumber
inst
Fungsi 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".Saya pikir satu-satunya solusi lengkap untuk melaporkan pemberitahuan dengan
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.
sumber
Satu-satunya cara untuk mengetahui apakah suatu variabel didefinisikan dalam lingkup saat ini (
$GLOBALS
tidak dapat dipercaya) adalaharray_key_exists( 'var_name', get_defined_vars() )
.sumber
Saya lebih suka menggunakan tidak kosong sebagai metode terbaik untuk memeriksa keberadaan variabel yang a) ada, dan b) bukan nol.
sumber
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 nilai0
dan1
. Jika Anda menggunakanempty()
untuk validasi dan pengguna memilih0
satu, Anda secara tidak sengaja akan menghapus "bidang yang diperlukan tidak boleh kosong". Lihat manual php.net/manual/en/function.empty.php