PHP'de bir değişkenin varlığını test etmenin en iyi yolu; isset () açıkça bozuk


187

Gönderen isset()docs :

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

Temel olarak, isset()değişkenin hiç ayarlanıp ayarlanmadığını kontrol etmez, ancak bunun dışında bir şeye ayarlanıp ayarlanmadığını kontrol eder NULL.

Buna göre, bir değişkenin varlığını kontrol etmenin en iyi yolu nedir? Gibi bir şey denedim:

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

( ayarlanmadığında @uyarıyı önlemek için gereklidir $v) ancak aşağıdakilere is_null()benzer bir sorunu vardır isset(): TRUEayarlanmamış değişkenlere geri döner ! Ayrıca şu şekilde görünür:

@($v === NULL)

aynen @is_null($v)öyle çalışıyor , bu yüzden de öyle.

PHP'de bir değişkenin varlığını nasıl güvenilir bir şekilde kontrol etmemiz gerekir?


Düzenleme: PHP'de ayarlanmamış değişkenler ve şu şekilde ayarlanmış değişkenler arasında belirgin bir fark vardır NULL:

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

PHP $a['b']var olduğunu ve bir NULLdeğeri olduğunu gösterir . Eklerseniz:

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

isset()fonksiyonla ilgili bahsettiğim belirsizliği görebilirsiniz . Bunların üçünün de çıktısı var_dump()s:

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

Daha fazla düzenleme: iki şey.

Bir, bir kullanım örneği. Bir dizi, SQL UPDATEdeyiminin verilerine dönüştürülür; burada dizi anahtarları tablonun sütunlarıdır ve dizinin değerleri her sütuna uygulanacak değerlerdir. Tablonun sütunlarından herhangi biri, dizideki NULLbir NULLdeğer iletilerek belirtilen bir değeri tutabilir . Sen ihtiyacım var olmayan bir dizi anahtarına arasında ayrım için bir yol ve bir Dizi değerinin ayarlanmasının yanı sıra NULL; bu, sütunun değerini güncellememek ile sütunun değerini güncellemek arasındaki farktır NULL.

İkincisi, Zoredache'nin cevabı , array_key_exists()yukarıdaki kullanım durumum ve herhangi bir global değişken için doğru çalışıyor:

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

çıktılar:

bool(true)
bool(false)

Düzgün hemen her yerde kolları beri var ve ayarlanır değişkenler yok değişkenler arasında herhangi bir belirsizlik var olmak görebilirsiniz NULL, ben arıyorum array_key_exists()PHP resmi en kolay yolu gerçekten bir değişkenin varlığını denetlemek için .

(Sadece düşünebileceğim diğer bir durum , belgelerineproperty_exists() göre , ayarlanmama ve ayarlanma arasında düzgün bir şekilde ayrım yapmasına benzer şekilde çalışan sınıf özellikleri içindir .)array_key_exists()NULL


Kontrol edemezsiniz - ama neden kontrol etmeniz gerekiyor?
Çok fazla php

12
NULL, PHP'de çok özel bir anlama sahiptir ve bir değişkenin ayarlanıp ayarlanmamasından tamamen ayrı bir kavramdır.
chazomaticus

33
Null ile varolmayan arasında ayrım yapmak için sebepler vardır . Örneğin, veritabanı tablosundaki bir satırı temsil edecek bir nesne oluşturuyorsunuz. Satırdaki her sütun için, yalnızca nesnenin getter yöntemiyle erişilebilen özel bir değişken oluşturursunuz. Bir sütun değerinin boş olduğunu varsayalım. Şimdi bu getter yöntemi, tabloda böyle bir sütun olup olmadığını veya bu nesnenin orada null değerinin olup olmadığını nasıl bilebilir? Neyse ki, benim durumumda, özel değişken aslında özel bir dizide bir girdi, bu yüzden array_key_exists kullanabilirsiniz, ancak bu gerçek bir sorundur.
Nathan Long

1
PHP'nin yeni sürümlerinden kaldırıldı, evet. Ne yazık ki, PHP'nin her dağıtımından gitmedi. Ayrıca, dizi öğeleri veya değişkenler hakkında konuşup konuşmadığımızı tartışmak anlamsız bir anlamsal detay gibi görünüyor. Hangi standartlara uymanız gerektiğini düşündüğünüzden bağımsız olarak, PHP dilinde bir tutarsızlık etrafında nasıl çalışılacağını bilmek yararlıdır.
chazomaticus

2
@chazomaticus Ancak değişkenler ve dizi elemanları temelde farklı şeylerdir ; onlarla aynı şeylerden bazılarını yapabilmeniz, bunların% 100 değiştirilebilir olduğu veya olması gerektiği anlamına gelmez. Burada "PHP dilinde tutarsızlık" yoktur, sadece sevmediğiniz / anlamadığınız bir şey yoktur. Gelince register_globals, hala HTTP isteğinden kaydedilen herhangi bir şey her zaman bir dize değil, çünkü böyle bir ayrım gerektirecek bir durum düşünmek için mücadele ediyorum null.
IMSoP

Yanıtlar:


97

Kontrol ettiğiniz değişken global kapsamda olursa şunları yapabilirsiniz:

array_key_exists('v', $GLOBALS) 

3
Ah ha! ŞİMDİ konuşuyorsun! Sınıf özellikleri için bunu nasıl yapardınız?
chazomaticus

22
Varyasyon olarak, kontrolün yerel kapsam değişkenleri için de çalışması gerekiyorsa, üzerinde bir $defined_vars = get_defined_vars();test yapabilir ve ardından üzerinden test yapabilirsiniz array_key_exists('v', $defined_vars);.
Henrik Opel

1
Bu benim için biraz çirkin görünüyor, ama aslında bir dizi elemanını kontrol ettiğinizde, çok daha mantıklı: isset($foo[$bar])olurarray_key_exists($bar, $foo)
Arild

property_existsbunun dışında umut verici görünüyor:> property_exists () işlevi __get magic yöntemi kullanılarak sihirli bir şekilde erişilebilen özellikleri algılayamıyor.
alexw

@alexw __get aracılığıyla "oluşturulan" değişkenler aslında mevcut değildir. __get, varolan herhangi bir verinin depolanıp saklanmadığına bakılmaksızın, istediği her şeyi döndürebilen, var olmayan değişkenler için yedek olarak kullanılan rastgele bir koddur.
Brilliand

46

Çeşitli tartışma ve cevaplara genel bir bakış sunmaya çalışmak:

Kullanılabilecek tüm yolların yerini alabilecek soruya tek bir cevap yoktur isset. Bazı kullanım durumları diğer işlevler tarafından ele alınırken, diğerleri incelemeye dayanmaz veya kod golfünün ötesinde şüpheli bir değere sahiptir. Neden Uzak "kırık" veya "tutarsız" olmaktan başka kullanım durumları göstermek issetiçin bireyin tepki nullmantıksal davranıştır.

Gerçek kullanım durumları (çözümlerle birlikte)

1. Dizi tuşları

Diziler ile değişkenlerin koleksiyonları gibi tedavi edilebilir unsetve issetbunlar sanki onları tedavi. Ancak yinelenebildikleri, sayılabildikleri vb. İçin eksik bir değer, değeri olan değerle aynı değildir null.

Bu durumda cevap etmektir kullanmak array_key_exists()yerineisset() .

Bu, diziyi işlev bağımsız değişkeni olarak kontrol etmesi gerektiğinden, dizinin kendisi yoksa PHP yine de "bildirimleri" yükseltir. Bazı durumlarda, geçerli olarak her bir boyutun ilk olarak başlatılmış olması gerektiği söylenebilir, bu nedenle bildirim işini yapmaktadır. Diğer durumlarda, array_key_existsdizinin her bir boyutunu sırayla kontrol eden bir "özyinelemeli" işlev bundan kaçınır, ancak temel olarak aynı olur @array_key_exists. Aynı zamanda nulldeğerlerin işlenmesine teğettir .

2. Nesne özellikleri

Geleneksel "Nesne Odaklı Programlama" teorisinde, kapsülleme ve polimorfizm nesnelerin temel özellikleridir; PHP en gibi sınıf tabanlı OOP uygulanmasında, kapsüllü özellikler sınıf tanımının bir parçası olarak bildirilen ve verilen erişim düzeylerini ( public, protectedveyaprivate ).

Bununla birlikte, PHP ayrıca bir dizinin anahtarları gibi bir nesneye dinamik olarak özellikler eklemenize izin verir ve bazı insanlar sınıfsız nesneler kullanır (teknik olarak, yerleşik örnekler stdClass , hiçbir yöntemi veya özel işlevselliği olmayan ) kullanır. çağrışımsal dizilere giden yol. Bu, bir işlevin kendisine verilen nesneye belirli bir özelliğin eklenip eklenmediğini bilmek isteyebileceği durumlara yol açar.

Dizi anahtarlarında olduğu gibi, nesne özelliklerini denetlemeye yönelik bir çözüm, makul olarak yeterli olarak adlandırılan dile dahil edilmiştirproperty_exists .

Tartışmalı gerekçesiz kullanım örnekleri

3. register_globalsve küresel ad alanının diğer kirliliği

Bu register_globalsözellik, adları HTTP isteğinin yönleriyle (GET ve POST parametreleri ve çerezler) belirlenen global kapsama değişkenler ekledi. Bu, hata ayıklama ve güvensiz kodlara yol açabilir, bu nedenle PHP 4.2, Ağustos 2000'i piyasaya sürdüğü ve Mart 2012'de piyasaya sürülen PHP 5.4'te tamamen kaldırıldığı için varsayılan olarak devre dışı bırakılmıştır . Ancak, bazı sistemlerin bu özellik etkinken veya taklit edilmiş halde hala çalışıyor olması mümkündür. globalAnahtar kelime veya $GLOBALSdiziyi kullanarak genel ad alanını başka şekillerde "kirletmek" de mümkündür .

Öncelikle, register_globalskendisi beklenmedik bir üretmek için olası değildir nullGET, POST beri, değişken ve çerez değerleri her zaman (dizelerle olacak ''hala dönen truedan isset) ve oturumda değişkenler programcı kontrolü altında tamamen olmalıdır.

İkincisi, bir değişkenin değerle kirlenmesi null, ancak bu daha önceki bir başlatmanın üzerine yazıldığında bir sorundur. Başlatılmamış bir değişkenin "üzerine yazılması" nullancak iki durum arasında başka bir yerde kod ayrılması durumunda sorun yaratacaktır, bu yüzden bu olasılık tek başına böyle bir ayrım yapmaya karşı bir argüman .

4. get_defined_varsvecompact

Gibi PHP'de Birkaç nadiren kullanılan fonksiyonlar, get_defined_varsve compactbunlar bir dizide tuşları sanki değişken isimleri tedavi etme imkanı. Global değişkenler için, super-global dizi$GLOBALS benzer erişime izin verir ve daha yaygındır. İlgili erişim alanında bir değişken tanımlanmamışsa bu erişim yöntemleri farklı davranacaktır.

Bu mekanizmalardan birini kullanarak bir değişken kümesini dizi olarak ele almaya karar verdikten sonra, normal işlemlerde olduğu gibi aynı işlemleri gerçekleştirebilirsiniz. Sonuç olarak, bakınız 1.

Yalnızca bu işlevlerin nasıl davranmak üzere olduğunu tahmin etmek için var olan işlevsellik (örneğin, "tarafından döndürülen dizide bir anahtar 'foo' olacak get_defined_varsmı?") Gereksizdir, çünkü işlevi çalıştırabilir ve hiçbir kötü etki olmadan öğrenebilirsiniz.

4a. Değişken değişkenler ( $$foo)

Değişken kümesini ilişkilendirilebilir bir diziye dönüştüren işlevlerle tam olarak aynı olmasa da, "değişken değişkenleri" ("bu diğer değişkeni temel alan bir değişkene atama ") kullanan çoğu durumda bunun yerine ilişkilendirilebilir bir dizi kullanmak üzere değiştirilebilir ve değiştirilmelidir. .

Değişken adı, temel olarak, programcı tarafından bir değere verilen etikettir; çalışma zamanında belirlerseniz, bu gerçekten bir etiket değil, bazı anahtar / değer deposundaki anahtardır. Daha pratik olarak, bir dizi kullanmıyorsanız, sayma, yineleme vb. anahtar-değer deposu "dışında" bir değişkene sahip olmak da imkansız hale gelebilir, çünkü aşırı yazılabilir $$foo.

İlişkilendirilebilir dizi kullanacak şekilde değiştirildikten sonra kod, çözüm 1'e uygun olacaktır. Dolaylı nesne özelliği erişimi (ör. $foo->$property_name) Çözüm 2 ile ele alınabilir.

5. yazmak issetçok daha kolayarray_key_exists

Bunun gerçekten alakalı olduğundan emin değilim, ancak evet, PHP'nin işlev adları oldukça uzun soluklu ve bazen tutarsız olabilir. Görünüşe göre, PHP'nin tarih öncesi sürümleri bir işlev adının uzunluğunu karma anahtarı olarak kullandı, bu yüzden Rasmus, htmlspecialcharsalışılmadık sayıda karaktere sahip olacakları gibi işlev adlarını kasten oluşturdu ...

Yine de, en azından Java yazmıyoruz, değil mi? ;)

6. Başlatılmamış değişkenlerin bir türü vardır

Değişken temelleri üzerinde manuel sayfa , şu ifadeye yer:

Başlatılmamış değişkenler, kullanıldıkları bağlama göre türlerinde varsayılan bir değere sahiptir

Zend Engine'de "başlatılmamış ancak bilinen tip" konusunda bir fikir olup olmadığından ya da bu ifadenin çok fazla okunup okunmadığından emin değilim.

Açık olan şey, bu sayfada başlatılmamış değişkenler için o sayfada açıklanan davranışlar, değeri olan bir değişkenin davranışı ile aynı olduğundan, davranışlarında pratik bir fark yaratmadığıdır null. Bir örnek almak için, her iki $ave $bbu kod tamsayı olarak sona erecek 42:

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

$b = null;
$b += 42;

(Birincisi, daha iyi kod yazmanızı sağlamak için bildirilmemiş bir değişken hakkında bir bildirim oluşturur, ancak kodun gerçekte nasıl çalıştığı konusunda herhangi bir fark yaratmaz.)

99. Bir fonksiyonun çalışıp çalışmadığını algılama

(Bunu son olarak tutmak, diğerlerinden daha uzun olduğu için. Belki daha sonra düzenleyeceğim ...)

Aşağıdaki kodu göz önünde bulundurun:

$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!';
}

Eğer some_functiondönebilirsiniz null, bu ihtimalin var echoolsa bile ulaşmış olmayacak some_testdöndü true. Programlayıcının amacı, daha $resultönce hiç ayarlanmadığı zamanı tespit etmekti , ancak PHP bunu yapmalarına izin vermiyor.

Ancak, bu yaklaşımla ilgili bir dış döngü eklerseniz ortaya çıkan başka sorunlar vardır:

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!';
    }
}

Çünkü $resultaçıkça hiçbir zaman başlatıldı ilk testi geçerken, daha sonraki testler geçti olsun ya da olmasın imkansız anlatmak için yapım bir değeri alacaktır. Bu, değişkenler düzgün bir şekilde başlatılmadığında son derece yaygın bir hatadır.

Bunu düzeltmek için, bir şeyin eksik olduğunu yorumladığım satırda bir şeyler yapmamız gerekiyor. En belirgin çözüm, asla geri dönemeyecek $resultbir "terminal değerine" ayarlamaktır some_function; bu ise null, kodun geri kalanı iyi çalışır. some_functionSon derece öngörülemeyen bir dönüş türü (muhtemelen kendi içinde kötü bir işarettir) olduğu için bir terminal değeri için doğal bir aday yoksa, $foundbunun yerine ek bir boolean değeri, örneğin kullanılabilir.

Düşünce deneyi tek: very_nullsabiti

PHP teorik nullolarak burada bir terminal değeri olarak kullanılmak üzere özel bir sabit - yanı sıra - sağlayabilir ; muhtemelen, bunu bir işlevden döndürmek yasadışı olurdu, ya da buna zorlanacaktı nullve muhtemelen bir işlev argümanı olarak iletmek için de geçerli olurdu. Bu, çok özel bir durumu biraz daha basit hale getirir, ancak kodu yeniden faktörlendirmeye karar verdiğinizde - örneğin, iç döngüyü ayrı bir işleve koymak için - işe yaramaz hale gelir. Eğer sabit fonksiyonlar arasında geçirilebilseydi, some_functionbunun geri dönmeyeceğini garanti edemezdiniz, bu yüzden artık evrensel bir terminal değeri olarak kullanışlı olmazdı.

Bu durumda başlatılmamış değişkenleri algılama argümanı, bu özel sabitin argümanına dayanır: Yorumu değiştirir unset($result)ve farklı bir şekilde ele $result = nullalırsanız, $resultbunun için bir "değer" girersiniz ve yalnızca belirli yerleşik işlevler tarafından algılanır.

İkinci deney deneyi: ödev sayacı

Sonuncunun ne istediğini düşünmenin bir başka yolu ifda "bir şey atadı mı $result?" Özel bir değer $resultolduğunu düşünmektense, bunu değişkenle ilgili "meta veri" olarak düşünebilirsin, biraz Perl'in "değişken renklendirme" gibi. Yani yerine issetsen diyebilir has_been_assigned_tove yerine unset, reset_assignment_state.

Ama öyleyse, neden bir boole'de duruyorsunuz? Testin kaç kez geçtiğini bilmek istiyorsanız ; meta verilerinizi bir tam sayıya genişletebilir get_assignment_countve reset_assignment_count...

Açıkçası, böyle bir özellik eklemek, dilin karmaşıklığı ve performansında bir değişime sahip olacaktır, bu nedenle beklenen kullanışlılığına dikkatlice tartılması gerekir. Bir very_nullsabitte olduğu gibi, sadece çok dar koşullarda yararlı olacaktır ve yeniden faktoringe benzer şekilde dirençli olacaktır.

Umarım açık olan soru, PHP çalışma zamanı motorunun neden normal kodu kullanarak açıkça yapmanıza izin vermek yerine bu tür şeyleri takip etmek istediğinizi önceden varsayması gerektiğidir.


Sınıflar ve özelliklerle ilgili olarak, özellik dizi olduğunda maalesef property_exists () çalışmaz, örneğin: Class {public $ property = array ()}. Bir hata atar.
Andrew

1
@Andrew Benim için iyi çalışıyor gibi görünüyor: 3v4l.org/TnAY5 Tam bir örnek vermek ister misiniz?
IMSoP

evet iyi çalışıyor gibi görünüyor, benim kurulum ile yanlış bir şey oldu. Yanlış alarm için özür dilerim :)
Andrew

20

Bazen belirli bir durumda hangi karşılaştırma işleminin kullanılacağını anlamaya çalışırken biraz kaybolurum. isset()yalnızca başlatılmamış veya açıkça boş değerler için geçerlidir. Null değerini geçmek / atamak, mantıksal bir karşılaştırmanın beklendiği gibi çalışmasını sağlamanın harika bir yoludur.

Yine de düşünmek biraz zor, bu yüzden farklı değerlerin farklı işlemler tarafından nasıl değerlendirileceğini karşılaştıran basit bir matris:

|           | ===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    |

Tabloya sığdırmak için etiketleri biraz sıkıştırdım:

  • $a; beyan edilmiş fakat atanmamış bir değişken anlamına gelir
  • ilk sütundaki diğer her şey atanmış bir değere karşılık gelir, örneğin:
    • $a = null;
    • $a = [];
    • $a = 0;
    • ...
  • sütunlar aşağıdaki gibi karşılaştırma işlemlerine başvurur:
    • $a === null
    • isset($a)
    • empty($a)
    • $a ? true : false
    • ...

Tüm sonuçlar boolean, trueyazdırılır ve falseçıkarılır.

Testleri kendiniz yapabilirsiniz, bu özü kontrol edin:
https://gist.github.com/mfdj/8165967


Belki bu sorunun kapsamı dışındadır, ancak operasyonun "0"tamlığı ve netliği için tabloya eklemek isteyebilirsinizempty
Rik Schaaf

17

Boş bir değişkenin var olup olmadığını test etmek için kompakt dil yapısını kullanabilirsiniz. Null değerler gösterilecekken, var olmayan değişkenler sonuç olarak ortaya çıkmayacaktır.

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

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

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

Örneğinizin durumunda:

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

Elbette global kapsamdaki değişkenler için array_key_exists () öğesini de kullanabilirsiniz.

Btw kişisel olarak var olmayan bir değişken ile bir null değeri olan değişken arasında anlamsal bir farkın olduğu veba gibi durumlardan kaçınırım. PHP ve diğer birçok dil sadece orada olduğunu düşünmüyor.


3
PHP yapmaz, ama diğer dillerin çoğunu söylemezdim . Değişkenleri bildiren herhangi bir dil, bir değişken bildirilmediyse bir hata atar, ancak bunları ayarlayabilirsiniz NULL. Anlamsal olarak, NULL"kaynak yok" anlamına gelmelidir, ancak bir değişkeni tanımlamamak bir programcı hatasıdır.
M Miller

1
@MMiller Elbette, ancak "kaynak yok" durumunda bir yol ve "programcı hatası" durumunda farklı bir yol izleyen kod yazmak oldukça saçmadır. Hata ayıklama sırasında bildirilmemiş değişkenleri tespit etmek istiyorsanız, herhangi bir dilde olası hataları bulmak gibi statik bir analiz aracı kullanın.
IMSoP

@ MMiller, Cool, bunu nasıl düşündün?
Pacerier

1
@MMiller Ancak, yanıttaki ifade açıkça "mevcut olmayan bir değişken" hakkında olduğundan ve karşı örneğiniz mevcut olmayan bir nesne özelliği / karma anahtarıyla ilgili olduğundan çürütme olarak çalışmaz . Bu davalar arasındaki ayrım sadece rastlantısal değildir.
IMSoP

1
@MMiller - bu daha iyi bir örnek. Yine de, 20 yıldan fazla süren katı dillerde programlama yaptıktan sonra, aralarında bir ayrım yapılması gereken undefinedve nullçok nadir olan durumlar, kaçırmamam. IMHO, ana kullanımı undefined"katı bir dilde programcı hatası" dır. Katı bir dilde, farklı bir duruma ihtiyacım olursa client did not state a value, duruma uygun bir değer beyan ederim ve test ederim. En kötü durumda, ayrı bir bayrak değişkeni eklemeniz gerekir. Ancak bunu nadiren yapmak, HER ZAMAN İKİ farklı değer dışı durumla başa çıkmaktan daha iyidir !
ToolmakerSteve

15

NULL'u açıklamak, mantıklı düşünmek

Sanırım tüm bunların açık cevabı ... Değişkenlerinizi NULL olarak başlatmayın, onları olması amaçlanan şeyle alakalı bir şey olarak canlandırın.

NULL'a doğru davran

NULL, NULL'nin anlamı olan "var olmayan değer" olarak ele alınmalıdır. Değişken PHP'nin var olduğu gibi sınıflandırılamaz, çünkü ne tür bir varlık olmaya çalıştığı söylenmemiştir. Ayrıca mevcut olmayabilir, bu yüzden PHP sadece "Güzel, çünkü zaten bir anlamı yok ve NULL bunu söylememin yolu" diyor.

Tartışma

Şimdi tartışalım. "Ama NULL, 0 veya FALSE veya '' demek gibidir.

Yanlış, 0-YANLIŞ- '', yine de boş değerler olarak sınıflandırılır, ancak bir tür değer veya bir soruya önceden belirlenmiş cevap olarak belirtilirler. YANLIŞ evet veya hayır cevabının cevabıdır, '' gönderilen başlığın cevabıdır ve 0 miktar veya zamanın cevabıdır.

NULL ne olursa olsun hiçbir cevap vermiyor, bize evet ya da hayır demiyor ve bize zamanı söylemiyor ve boş bir dize gönderildiğini söylemiyor. NULL'ı anlamanın temel mantığı budur.

özet

Bu, sorunu çözmek için tuhaf işlevler yaratmakla ilgili değil, beyninizin NULL'a bakışını değiştiriyor. NULL ise, herhangi bir şey olarak ayarlanmadığını varsayalım. Değişkenleri önceden tanımlıyorsanız, amaçladığınız kullanım türüne bağlı olarak bunları 0, YANLIŞ veya "" olarak önceden tanımlayın.

Bunu alıntı yapmaktan çekinmeyin. Mantıksal kafamın tepesinde :)


5
Mükemmel cevap. Birçok kez insanların bundan ya da bir dilin bu özelliğinden nasıl nefret ettikleri konusunda sıralandığını görüyorum. Ama sanki "bunu benim yolumdan yapmazsa, o zaman kırılmış" gibi görünüyorlar. Evet, kötü tasarım kararları var. Ancak çok yakın fikirli geliştiriciler de var!
curtisdf

23
Unset değişkeni ve değişken === null arasında BÜYÜK bir fark var. Biri yok, diğeri null değerine sahip. Null değerinin, hiçbir değerin doğru olmadığı anlamına geldiği iddiaları. Null null türünde bir VALUE. Mükemmel bir değerdir ve ne yazık ki php var olmayan bir değer olarak tedavi etmek için hiçbir nedeni yoktur. Varolmayan değişkenler null olsaydı ve mevcut her değişken null değilse ve değişkeni null değerine atamak bunu çözerdi. Ancak, işlevlerin gerçek değer olarak null döndürdüğü BİRÇOK durum vardır. Sonra berbatız, çünkü test etmek için kanlı bir yol yok.
enrey

2
Ben php, cehennemde değişken varlığını kontrol etmek için "gerekiyordu" biliyorum, hatta kontrol etmek için gerçek bir yolu yok. Ben php mümkün olmadığından, üzerine deppends kod yazmak için gitmeyeceğim. Bu php bir sınırlama. Belirsiz ve boş değişken arasında açıkça bir fark vardır, ancak php bunları ayırt etmek için hiçbir yol sağlamaz. Yine de çok fazla meta işlevsellik içsel olarak bağlıdır: mevcut olmayan var okumak uyarı üretir, isset($a['x'])boşsa size yanlış söyleyecektir x, ancak görünecektir count($a).. compactdahil olmak üzere tüm ayarlı değişkenler üzerinde çalışacaktır nulls.
enrey

3
Bu cevap büyük bir şekilde kusurludur: OO programlamasında null, "nesne yok" anlamına gelen mantıklı bir seçimdir. Örneğin, bir işlevin bir nesneyi döndürebileceği veya hiçbir nesneyi döndüremeyeceği olağandışı durumlarda, null bariz seçimdir. Teknik olarak PHP'de false veya boolean bağlamında false olarak kabul edilen başka bir değer kullanılabilir, ancak daha sonra bazı anlamsal saflığı kaybedersiniz. Böylece, boş çünkü, sonuçta bir nesneyi tutmak gerektiğini bir değişkeni başlatmak için son derece mantıklı bir değerdir olduğu bir hâle niyetiyle şeylerle alakalı.
chazomaticus

3
PHP tanımsız değişkenler için hatalar attığı sürece null için hata atmadığı sürece bir fark vardır. Eğer null ve undefined gerçekten aynı kavram olsaydı, PHP varsayılan tanımsız / bildirilmemiş değişkenleri null olarak varsaymalı ve asla bir hata atmamalı, ama kimse bunu istemiyor çünkü bu bir gelişim kabusu. Null ve undefined, değer semantiği bağlamında gerçekten farklı olmayabilir, ancak açık ve hata ayıklanabilir kod yazmak söz konusu olduğunda çok farklıdır.
Chris Middleton

9

Nesne özellikleri, property_exists tarafından varlığını kontrol edebilir

Birim testinden örnek:

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");
    }
}

4

Greatbigmassive'ın NULL'ın ne anlama geldiğine ilişkin tartışmasına ek olarak , "bir değişkenin varlığı" nın gerçekte ne anlama geldiğini düşünün.

Birçok dilde, kullanmadan önce her değişkeni açıkça bildirmeniz gerekir ; bu türünü belirleyebilir, ancak daha da önemlisi kapsamını açıklar . Değişken, kapsamının her yerinde "var" dır ve bunun dışında hiçbir yerde - bütün bir işlev veya tek bir "blok" olsun.

Kapsamı içinde bir değişken , programcı olarak sizin seçtiğiniz bir etikete bir anlam ifade eder . Kapsamının dışında, bu etiket anlamsızdır (aynı etiketi farklı bir kapsamda kullanıp kullanmadığınız temel olarak anlamsızdır).

PHP'de değişkenlerin bildirilmesine gerek yoktur - ihtiyacınız olduğu anda hayata geçerler. Bir değişkene ilk kez yazdığınızda, PHP o değişken için hafızaya bir giriş atar. Şu anda bir girişi olmayan bir değişkenten okursanız, PHP bu değişkenin değere sahip olduğunu düşünür NULL.

Bununla birlikte, otomatik kod kalite dedektörleri genellikle bir değişkeni ilk olarak "başlatmadan" kullanırsanız sizi uyarır. Birincisi, bu, tayin etmek, $thingIdancak okumak $thing_id; ancak ikincisi, bu değişkenin anlamını hangi kapsamda olduğu gibi, bir bildirimin de olduğu gibi düşünmeye zorlar.

Bir değişkenin "var olup olmadığına" önem veren herhangi bir kod, bu değişkenin kapsamının bir parçasıdır - başlatılmış olsun veya olmasın, bir programcı olarak kodun o noktasında bu etikete anlam verdiniz. Onu kullandığınız için, bir anlamda "var" olmalıdır ve eğer varsa, örtük bir değere sahip olmalıdır; PHP'de bu örtük değer null.

PHP'nin çalışma biçimi nedeniyle, varolan değişkenlerin ad alanına anlam verdiğiniz etiketlerin bir kapsamı olarak değil, bir tür anahtar / değer deposu olarak davranan kod yazmak mümkündür. Sen, mesela, bunun gibi bir kod çalıştırabilir: $var = $_GET['var_name']; $$var = $_GET['var_value'];. Sadece yapabileceğiniz için iyi bir fikir olduğu anlamına gelmez.

Görünüşe göre PHP'nin ilişkilendirilebilir diziler olarak adlandırılan anahtar / değer depolarını temsil etmenin çok daha iyi bir yolu var. Ve bir dizinin değerleri değişkenler gibi ele alınabilse de, dizideki işlemleri bir bütün olarak da gerçekleştirebilirsiniz. İlişkilendirilebilir bir diziniz varsa, bunu kullanarak bir anahtar içerip içermediğini test edebilirsiniz array_key_exists().

Nesneleri, özellikleri dinamik olarak ayarlayarak benzer bir şekilde kullanabilirsiniz property_exists(); bu durumda , tam olarak aynı şekilde kullanabilirsiniz. Tabii ki, sen bir sınıf tanımlarsanız, bunu hangi özellikleri ilan edebilir hatta birisini seçebilir - public, privateve protectedkapsamı.

Başlatılmamış (veya açıkça ) bir değişken (bir dizi anahtarının veya bir nesne özelliğinin aksine) ile değeri olan bir değişken arasında teknik bir fark olsa da, bu farkı anlamlı olarak kabul eden herhangi bir kod değişkenleri kullanılmayacak şekilde kullanıyor.unset()null


1
Çok iyi noktalar, ancak tam olarak soruya bir cevap değil.
chazomaticus

1
"PHP'de bir değişkenin varlığını nasıl güvenilir bir şekilde kontrol etmemiz gerekiyor?" cevabım "sen değilsin ve işte sebebi". Bu cevap ve greatbigmassive en Hem de cevap örtülü soru "neden yaptığını isset()bu şekilde davranır?".
IMSoP

"Şu anda bir girişi olmayan bir değişkenden okursanız, PHP bu değişkeni NULL değerine sahip olarak kabul eder." Bu yanlış. Tanımlanmamış bir değişken basitçe tanımsızdır. Erişmeye çalıştığınızda null değeri dönebilir, ancak bu önemsizdir.
Hugo Zink

@HugoZink Neyle alakasız? Tanımlanmamış bir değişkenin değeri üzerinde yaptığınız herhangi bir test, değerin olduğunu size söyleyecektir null. Bu değerin, bakmadan önce var olup olmadığı, filozoflar için bir sorudur, ancak gözlemlenebilir herhangi bir davranış söz konusu olduğunda, değer tutarlıdır null.
IMSoP

3

issetdeğişkenin ayarlanıp ayarlanmadığını ve varsa değerinin NULL olup olmadığını kontrol eder . İkinci kısım (benim görüşüme göre) bu işlev kapsamında değildir. Bir değişkenin NULL olup olmadığını veya açıkça NULL olarak ayarlandığından emin olmak için iyi bir geçici çözüm yoktur .

İşte olası bir çözüm:

$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

Diğer geçici çözüm çıktısını araştırmaktır 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

2

NULL ile ilgili mantığınıza katılmıyorum ve NULL hakkındaki zihniyetinizi değiştirmeniz gerektiğini söylemek sadece garip.

Bence isset () doğru tasarlanmamıştır, isset () değişkenin ayarlanmış olup olmadığını söylemelidir ve değişkenin gerçek değeri ile ilgilenmemelidir.

Bir veritabanından döndürülen değerleri kontrol ediyorsanız ve sütunlardan birinin NULL değeri varsa, değer NULL olsa bile hala var olup olmadığını bilmek istersiniz ... nope dont trust isset () burada.

aynı şekilde

$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 () şu şekilde çalışacak şekilde tasarlanmış olmalıdır:

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

Bu şekilde, türleri kontrol etmek için programcıya bırakıyoruz ve değer NULL olduğu için orada olmadığını varsaymak için isset () 'e bırakmıyoruz - sadece aptal tasarım


Örneğiniz bir değişkenin varlığını değil, bir dizi anahtarının varlığını kontrol etmektir. Buna bir çözüm var array_key_exists. Gerçek bir değişken olup olmadığını asla çalışma zamanında bilmediğiniz bir durumda olmamalısınız.
IMSoP

@chazomaticus Peki, asla register_globals'ın açık olduğu bir durumda olmamalısınız, bu yüzden bu ifadenin yanındayım.
IMSoP

Kabul ediyorum. Yine de, herkes kodlarının nereye yerleştirildiğini kontrol edemez. Durumların "olması gerekip gerekmediği" her durum için bilgi sahibi olmak yararlıdır.
chazomaticus

@chazomaticus Sorununuz buysa, register_globalscevabınız bir değişiklik değildir isset(). PHP el kitabında, register_globalsçalışma zamanı yerine tasarım zamanında çözülen "genellikle değişkenleri ilk önce başlatmak için gerçekten iyi bir programlama uygulamasıdır" den bahsedilir . Çalışma zamanında bununla başa çıkmak için bir işlev veren bir SSS girişi de vardır unregister_globals().
IMSoP

2

Buna hızlı bir iki sent ekleyeceğim. Bu senaryo hatası raporlama ile aynı sonuç gibi görünüyor, çünkü bu konu kafa karıştırıcı bir nedeni olduğunu değil tam tarih:

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

Bu sonuçtan, $a = nullhiç tanımlamamak ve tanımlamamak arasındaki farkın $bhiçbir şey olmadığını varsayabilirsiniz .

Krank hatası bildiriliyor:

NULL

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

Not: tanımlanmamış bir değişken hatası attı, ancak çıkış değeri var_dumphala NULL.

PHP'nin bir null değişkeni ile tanımlanmamış bir değişkeni ayırt etme konusunda içsel bir yeteneği vardır. Bana öyle geliyor ki bunu kontrol etmek için yerleşik bir fonksiyon olmalı.

Kabul edilen cevabın çoğunlukla iyi olduğunu düşünüyorum, ama eğer uygulayacak olsaydım, bunun için bir sargı yazardım. Bu cevapta daha önce de belirtildiği gibi , bunun gerçekten bir sorun olduğu bir durumla karşılaşmadığımı kabul etmeliyim. Neredeyse her zaman değişkenlerimin ya ayarlandığı ya da tanımlandığı ya da tanımlanmadığı (tanımsız, ayarlanmamış, boş, boş, vb.) Bir senaryo ile karşılaşıyorum. Gelecekte böyle bir durum gerçekleşmeyeceğini söylemek değil, ama oldukça benzersiz bir sorun gibi göründüğü gibi PHP devs bunu koymak için rahatsız değil şaşırmadım.


Tanımlanmamış değişkenler üzerindeki uyarı, programcıya kodda yanlış bir şey yaptıklarına dair bir ipucudur. Dış hata ayıklama (bunun dışında dil araçları dışında), böyle bir durumu algılamak için bir programa asla ihtiyaç duyulmamalıdır, çünkü programcı her zaman hangi değişkenleri bildirdiklerini bilmelidir.
IMSoP

1

Aşağıdakileri çalıştırırsam:

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

Bir hata alıyorum:

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

Aşağıdakileri çalıştırırsam:

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

Hatayı almıyorum.

Ayarlanması gereken bir değişkenim varsa, genellikle aşağıdaki gibi bir şey yaparım.

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

veya

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

Bu şekilde, daha sonra komut dosyasında, güvenli bir şekilde $ foo kullanabilir ve "ayarlandığını" ve varsayılan olarak null olduğunu bilirim. Daha sonra if ( is_null($foo) ) { /* ... */ }değişkenin var olduğunu kesin olarak bilmem gerekiyorsa ve bilmem gerekirse yapabilirim .

Tam isset belgeleri , başlangıçta yapıştırılandan biraz daha fazlasını okur. Evet, önceden ayarlanmış ancak şimdi null olan bir değişken için false değerini döndürür, ancak bir değişken henüz ayarlanmamışsa (hiç) ve unset olarak işaretlenmiş herhangi bir değişken için false değerini döndürür. Ayrıca NULL baytının ("\ 0") null olarak değerlendirilmediğini ve true değerini döndüreceğini de not eder.

Bir değişkenin ayarlanıp ayarlanmadığını belirleyin.

Bir değişken unset () ile ayarlanmamışsa, artık ayarlanmayacaktır. NULL olarak ayarlanmış bir değişkeni test ediyorsanız isset () işlevi FALSE değerini döndürür. Ayrıca bir NULL baytının ("\ 0") PHP NULL sabitine eşdeğer olmadığını unutmayın.


Dokümanları bu bağlantıdan çıkardı. Sağladığınız bağlantıdaki açıklama bölümünün ilk cümlesini, ikinci paragrafını okuyun.
Zoredache

Bu basit komut dosyaları için kötü bir uygulama değildir, ancak karmaşık (örneğin büyük OO) projelerde, mümkün değildir. Ayrıca, yukarıda söylediğim gibi, is_null () ayarlanmamış değişkenler için TRUE değerini döndürür, bu yüzden bir PHP uyarısından kaçınmak dışında söylediklerinizi yapmanız için hiçbir neden yoktur.
chazomaticus

1
İyi tasarlanmış "büyük OO" projeleri için bu neden bir sorun olur? Neden ilk kullanımından önce ayarlanmamış bir yöntem gövdesinde $ foo alırdınız?
Beau Simensen

1

Kullanmayı deneyin

unset($v)

Bir değişkenin ayarlanmadığı tek zaman, özellikle ayarlanmadığı zamandır ($ v). Görünüşe göre 'varoluş' anlamınız PHP'nin tanımından farklı. NULL kesinlikle var, NULL.


Ne anlatmak istediğinden emin değilim. Bir diziniz varsa, bir öğe 'a' ile, 'b' öğesinin PHP'de olmaması için 'b' öğesini () ayarlamak zorunda değilsiniz, sadece mevcut değildir. $ GLOBALS dizisinin öğeleri olarak düşünebileceğiniz global değişkenlerle aynı şey.
chazomaticus

1
Ancak NULL değeri olan bir değişkenin aslında var olduğunu kabul ediyorum.
chazomaticus

0

PHP programlama tüm yıllarında, isset()null değişken üzerinde yanlış döndürme ile ilgili bir sorunla karşılaşmadım söylemek zorundayım . OTOH, isset()bir boş dizi girişi başarısız - sorunla karşılaştım - ancak array_key_exists()bu durumda doğru çalışır.

Bazı karşılaştırmalar için, Icon açıkça kullanılmayan bir değişkeni döndürme olarak tanımlar, &nullböylece ayarlanmamış bir değişkeni de kontrol etmek için Icon'da is-null testini kullanırsınız. Bu işleri kolaylaştırır. Öte yandan, Visual BASIC değeri olmayan bir değişken (Null, Empty, Nothing, ...) için birden fazla duruma sahiptir ve çoğu zaman bunlardan birden fazlasını kontrol etmeniz gerekir. Bu bir hata kaynağı olarak bilinir.


0

Empty () işlevi için PHP Manual'a göre, "Bir değişkenin boş olarak değerlendirilip değerlendirilmeyeceğini belirleyin. Bir değişken boş kabul edilirse veya değeri FALSE'a eşitse. Empty (), değişkeni yok. " (Vurgu.) Bu, boş () işlevinin, Soru başlığı başına "bir değişkenin PHP'deki varlığını test etmenin en iyi yolu" olarak nitelendirilmesi gerektiği anlamına gelir.

Ancak, bu yeterince iyi değildir, çünkü empty () işlevi var olan ve NULL olarak ayarlanmış bir değişken tarafından kandırılabilir.

Daha iyi bir şey sunmak için önceki cevabımı kesiyorum, çünkü orijinal cevabımdan daha az zahmetli (bu kesintiyi takip eden karşılaştırma için).

  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
  }

İki basit kod satırı, bir değişkenin tanımsız olup olmadığını ortaya çıkarmak için yukarıdaki işlevi kullanabilir:

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

Bu iki satırı aşağıdaki örnek gibi uygun bir şeyle takip edebilirsiniz:

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

Ben fonksiyon içinde ob_start () ve ($ testvar === null) çağrısı koymak ve sadece fonksiyona değişken geçmek istedim, ama çalışmıyor. Değişkenin işlevine "başvuru ile geç" işlevini kullanmaya çalışsanız bile, tanımlanmış olan BECOMES değişkeni ve işlev daha önce tanımlanmamış olduğunu algılayamaz. Burada sunulanlar, yapmak istediklerim ile gerçekte çalışanlar arasında bir uzlaşma.

Yukarıdaki, her zaman "Tanımsız değişken" hata iletisine girmekten kaçınmanın başka bir yolu olduğunu gösterir. (Buradaki varsayım, böyle bir mesajın önlenmesinin, bir değişkenin tanımlanıp tanımlanmadığını test etmek istediğiniz nedenidir.)

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

$ Testvar'ınıza bir şey yapmadan önce bu işlevi çağırmanız yeterlidir:

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

Yeni başlatılan değişkenin değeri elbette null olarak ayarlanmıştır!

(Kesinti sona erer)

Yani, biraz çalıştıktan ve denedikten sonra, çalışması garanti edilen bir şey:

 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
 }

Açıklama: $ er değişkeni "hata yok" varsayılan değerine sıfırlandı. Bir "işleyici işlevi" tanımlanmıştır. $ Testvar (tanımsız olup olmadığını bilmek istediğimiz değişken) ön boş () fonksiyon testini geçerse, daha kapsamlı testi yaparız. Önceden tanımlanmış işleyici işlevini kullanmak için set_error_handler () işlevini çağırırız. Sonra, tanımlanmamışsa HATA TETİKLEYECEK $ testvar içeren basit bir kimlik karşılaştırması yaparız. İşleyici işlevi hatayı yakalar ve özellikle hatanın nedeninin değişkenin tanımsız olup olmadığını görmek için test eder. Sonuç, $ testvar'ın tanımlanıp tanımlanmadığından emin olmak için daha sonra istediğimiz her şeyi yapmak için test edebileceğimiz $ er hata bilgisi değişkenine yerleştirilir. Bu sınırlı amaç için işleyici işlevine ihtiyacımız olduğundan, orijinal hata işleme işlevini geri yükleriz. "MyHndlr" işlevinin yalnızca bir kez bildirilmesi gerekir; diğer kod, uygun olan her yere kopyalanabilir, $ testvar veya bu şekilde test etmek istediğimiz diğer değişkenler için.


1
Amaç, değişkenlerinizin bildirilmediğini bildirmekten kaçınmaksa, çözüm, doğru şekilde bildirmek için kodunuzu düzeltmektir. Sizin instişlevi temelde gibidir @hatasız bastırma operatörü: "Ben burada bir şey yanlış yaptığımı biliyorum, ama sadece o mesajın gerçekten herhangi bir şekilde benim kod çalışmasını değiştirmeden gitmesini istiyorum".
IMSoP

Tespit yöntemleri, diğer taraftan, ustaca, ama yine de onlar için onlar asla onlar yakalamak çok uyarı mesajları yankı dışında herhangi bir kullanmamanız gerektiğine inanıyorum. (Büyük olasılıkla çıktı arabelleğe alma sürümünüzün
hata_ raporlama

0

Ben sadece tam çözüm olduğunu düşünüyorum bildirimleri rapor ile

error_reporting(E_ALL); // Enables E_NOTICE

Ancak, tanımlanmamış değişkenler, sabitler, dizi anahtarları, sınıf özellikleri ve diğerleri arasında oluşturulan tüm bildirimleri düzeltmeniz gerekecektir. Bunu yaptıktan sonra, null ve bildirilmemiş değişkenler arasındaki fark hakkında endişelenmenize gerek kalmaz ve belirsizlik ortadan kalkar.

Bildirim raporunu etkinleştirme her durumda iyi bir alternatif olmayabilir, ancak bunu etkinleştirmek için iyi nedenler vardır:

Neden E_NOTICE hatalarını düzeltmeliyim?

Benim durumumda bir proyektte onsuz bir yıldan fazla çalışıyordu, ancak değişkenleri bildirmeye dikkat etmek için kullanıldı, bu yüzden geçiş hızlıydı.


0

Bir değişkenin geçerli kapsamda tanımlanıp tanımlanmadığını bilmenin tek yolu ( $GLOBALSgüvenilir değildir) array_key_exists( 'var_name', get_defined_vars() ).


1
Sanırım daha önce başka pek çok kişi bunu söyledi, yoksa yanıldım mı?
Stephan Vierkant

-1

A) var ve b) null olmayan bir değişken olup olmadığını kontrol etmek için en iyi yöntem olarak boş değil kullanmayı tercih ederim.

if (!empty($variable)) do_something();

2
empty()değişkenin null olup olmadığını kontrol etmez, false-y olup olmadığını kontrol eder, örneğin ""(boş bir dize), 0(tam sayı olarak 0), 0.0(kayan nokta olarak 0), "0"(dize olarak 0) NULL, FALSE, array()(boş bir dizi) ve $var;(bildirilen ancak değeri olmayan bir değişken). Eğer değerlerle İki girişli bir formda gerekli radyo alanını olduğunu varsayalım 0ve 1. empty()Doğrulama için kullanır ve kullanıcı bunu seçerse, 0yanlışlıkla "zorunlu alan boş olamaz" hatası verirsiniz. Manuel Bkz php.net/manual/en/function.empty.php
Halil Özgür
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.