PHP neden “0” a boole bağlamında FALSE olarak davranıyor?


12

"0", bir karakter içeren bir dize olarak, sezgisel olarak boş bir şey değildir. PHP diğer programlama dillerinin aksine bir boole dönüştürüldüğünde neden FALSE olarak davranıyor?


2
kopyası: stackoverflow.com/questions/523643/… . PHP ve javascript ile aynıdır.
Walfrat

5
Çünkü PHP hem kendisi hem de diğer tüm programlama dilleriyle mümkün olduğunca tutarsız olmak için büyük çaba harcıyor.
David Arno

2
@DavidArno Aksine, tutarlı olmak için elinden geleni yapıyor ; dizeleri otomatik yayınlamaya başladığınızda (genellikle URL'lerden veya istek gövdelerinden farklılık gösteren bir dilde çok kullanışlı) bu mantığı takip etmeniz gerekir. Eğer '0'olarak kabul edilir 0in $x + 1, neden olarak da ele alınmaması gerektiğini 0ve bu nedenle false, içinde if ( $x )?
IMSoP

1
@DavidArno tam olarak;)
linuxunil

1
@DavidArno Kayıp dökümler yapmaya başladığınızda, bazı tutarsızlıkların kaçınılmaz olduğunu düşünüyorum; tutarlı çözüm, bazı kalıpların reddedilmesini ve gerisini çok dikkatli bir şekilde tasarlamayı içerir. Yine de çok az popüler dil sıfırdan tasarlanmıştır; çoğu ya kazara popüler olan deneylerden ya da farklı amaçlara ve bagajlara sahip eski dillerden gelişir. Çok sağlam bir teorik tasarıma sahip olan C # bile, hiçbir zaman olduğu kadar evrensel olması amaçlanmayan C'den bir mirasa sahiptir. "Tutarsız olmak için büyük çaba sarf etmek" gibi snark, bir spor maçında ref'de bağırmak gibidir.
IMSoP

Yanıtlar:


12

PHP, dizgi girişiyle (URL parametreleri veya tarayıcıdaki bir formdan POST istekleri) sık sık uğraştığınız web istekleriyle kullanılmak üzere tasarlanmıştır (veya daha doğrusu gelişmiştir). Bu nedenle, dizeleri otomatik olarak diğer türlere dökecektir.

Bu basit bir örnek olduğunu '1' + '2'verir 3, değil bir hata veya '12' veya başka bir yorumunu. Aynı mantıkla, dize '0'sayısal olarak kullanılabilir 0.

Bu arada, birçok dilde olduğu gibi PHP, boolean'a yayınlandığında belirli değerleri "yanlış" olarak kabul eder - dediğiniz gibi sezgisel olarak "boş" olanlar. Buna sayısal 0, boş dize ''ve boş dizi de dahildir []. Bir ififadede, ifade açıkça boole'ye dökülür if ( 0 ), aynı şekilde if ( false ).

Bu iki şeyi bir araya getirmek, bir muamma elde edersiniz: bir yandan, '0'boş bir dize dediğiniz gibi ; Öte yandan, bunun 0"boş" bir sayısal olarak kullanılabileceğini söyledik . PHP '0'"sıfırlık" ı "sersemlik" den daha önemli olarak ele almayı tercih eder, bu yüzden "falsy" olarak kabul edilir.

Kısacası '0' == 0 == false:; veya(bool)'0' === (bool)(int)'0'


Birisi sadece PHP'yi savunmaya ve soruyu ucuz ve cahil bir şakadan başka bir şeyle cevaplamaya cesaret ettiğim için cevabımı küçümsedi mi? Yoksa cevabımda belirtmek istedikleri yanlış veya yararsız bir şey mi var?
IMSoP

1
Ben PHP bunu aynı " "0" yanlış" davranışı olan Perl'den aldı düşünüyorum . Perl'de, tam olarak dize "0"ve sayı arasında kullanıcı tarafından görülebilir bir fark yoktur 0- JSON ile çalışırken rahatsız edici, ancak metin verilerini kullanırken çok sezgisel. Bu durumda 0, dizenin falsey olmadan sayının falsey olması imkansızdır "0". PHP ve JavaScript bu tasarım kararı ödünç, ama yine de örtük dönüşüm izin verirken dizeleri / bool değerlerden oluşan / sayısal türlerini ayırt ederek bazı karışıklıklara ekleyin (PHP: 0 == "0 foo", 0 == falsefakat "0 foo" == true: ==geçişli değildir)
amon

@amon Evet, Perl, eqdizgi eşitliği gibi ekstra işleçlerle, işlenenleri belirli bir türe zorlayan (neredeyse) tüm işleçlerin ve yerleşik işlevlerin ilginç yaklaşımını benimser . Bununla birlikte, bu onu kayıplı dökümlerin "0 foo"geçişsizliğinden kurtarmaz: boolean bir bağlamda doğrudur, ancak 0altına eşittir ==. Yani if ( ! $foo ) ..ve $false = (1 == 2); if ( $foo == $false ) ... aynı sonucu vermezler. Sanırım bu dili sürekli olarak tedavi edebilecek bir "boolean eşitliği" operatörü eksik ...
IMSoP

Sayısal olarak değerlendirildiğinde "0" 0 olmasına rağmen, bir boole bağlamında (örneğin bir if ifadesinde) bir dize kullandığımızda, sayısal değeriyle ilgilenmiyoruz. Sayısal olarak yorumlamak istiyorsak, örneğin bir sayı ile karşılaştırırız $_POST['id'] == 0, bu da kullanıcı girişini sayı olarak ele almak istediğimizi netleştirir.
Michael Tsang

1
@MestreLion Bu örnek PHP yerine Perl idi. Önemli fark Perl'de ayrı bir boolean tipi $falseolmamasıdır 0; yazdığınızda $foo == $falsePerl, bir boole karşılaştırması istediğinizi bilmiyor ve bunun yerine int'i yayınlıyor. PHP'de bu gerçekleşmez, çünkü $falseboolean false, bu yüzden ==boolean için yayınlar, aynı sonucu verir!
IMSoP

3

Booleans hakkındaki PHP belgelerine göre şunları söylüyor:

Boolean dönüştürürken, aşağıdaki değerler olarak kabul edilir FALSE
...
boş dize ve dize "0"
...

Aksi takdirde:

Diğer her değer TRUE (herhangi bir kaynak dahil) olarak kabul edilir.

Eğer koşarsan:

var_dump((bool) "0");

Yazdırılacak:

BOOL (yanlış)

Yani beklendiği gibi çalışıyor.


Sorunuzu açıkça cevaplamak için:

Bununla birlikte, çoğu durumda döküm gereksizdir, çünkü bir operatör, fonksiyon veya kontrol yapısı bir boole argümanı gerektiriyorsa bir değer otomatik olarak dönüştürülecektir.

PHP'nin "AutoCast" "0" dır tamsayı 0, artığını edeceğini Bu araçlar FALSEbir söylemek gibi bir kontrol yapısı içinde de if()bildiri.


Açık döküm ihtiyacı yerine, boole dönüştürüldüğünde "0" yerine FALSE olarak davranan tasarım kararının mantığını bilmek istiyorum.
Michael Tsang
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.