if ('constant' == $ değişken) - if ($ değişken == 'sabit')


48

Son zamanlarda PHP'de ve özellikle WordPress çerçevesinde çok çalışıyorum. Şeklinde bir çok kod fark ediyorum:

if ( 1 == $options['postlink'] )

Görmeyi beklediğim yer:

if ( $options['postlink'] == 1 )

Bu, belirli dillerde / çerçevelerde bulunan bir sözleşme mi? Eski yaklaşımın ikincisine tercih edilmesinin herhangi bir nedeni var mı (işlem perspektifinden veya ayrıştırma perspektifinden ve hatta insan bakış açısından)?

Yoksa sadece zevk meselesi mi? Bir test yaparken her zaman daha iyi olduğunu düşündüm, bazı sabitlere karşı test edilen değişken öğesinin solda olması. Soruyu doğal dilde soracağımız yolu daha iyi gösteriyor gibi görünüyor: "pasta çikolata ise", "pasta çikolata ise".


1
Asla böyle bir kod yazmam ama dürüst olmak gerekirse "çikolata pastanın tadıysa" kulağa doğal geliyor. Doğal dil daha esnektir.
Rick Sladkey

4
@Rick Dilde doğal görünebilir, ancak böyle bir kod gördüğünüzde, ne yapmaya çalıştığını düşünmek için önce (belki sadece bir saniye) durmanız gerektiğini reddedemezsiniz.
Edgar Gonzalez,

4
@Edgar Gonzalez: Kabul, kod olarak kesinlikle karşıyım.
Rick Sladkey

3
Kodun Tamamlanmış 2. Basımının 19. Bölümü ("Boole İfadeleri: Boole İfadeleri ile İlgili Genel Sorunlar" bölümü altında) aslında bu uygulamayı, buradaki cevapların çoğunda belirtilen tam nedenden ötürü önermektedir: Karşılaştırma yapıldığında C türevli dillere atanmayı önlemek .
CraigTP

4
Bunları sık sık "Yoda Koşulları" olarak adlandırıyordum
Brian

Yanıtlar:


83

Bunu yapmanın temel nedeni ("Yoda koşullu"), yanlışlıkla =eşit karşılaştırma operatörü ( ==) yerine, bir atama operatörü ( ) kullandığınız kazaları önlemektir .

Yani, yapma hatası yaptıysanız:

$foo = 5;
if ($foo = 1) {
  // Stuff
}

Bu ifade true(ya da PHP gibi bazı diller söz konusu olduğunda bir truthy değeri) olarak değerlendirilecek ve bulması zor bir hatayla karşılaşacaksınız.

Ama yaptıysan:

$foo = 5;
if (1 = $foo) {
  // Stuff
}

$fooBir tamsayıya atayamayacağınız için ölümcül bir hata alırsınız .

Ancak belirttiğiniz gibi, sıranın tersine çevrilmesi genellikle işleri daha az okunabilir hale getirir. Bu nedenle, birçok kodlama standardı (ancak WordPress dahil hepsi değil ) $foo == 1böcek avı yararlarına rağmen bunu önerir veya gerektirir 1 == $foo.

Genel olarak, benim tavsiyem, varsa kodlama standardının ne olduğuna uymaktır, eğer varsa: WordPress için, Yoda koşullarını kullanmak anlamına gelir.

Olmadığında ve akranlarınızla bir fikir birliğine varmak imkansız olduğunda, bayinin tercihidir.


2
Bu tür sorunlardan kaçınmak için (uzun zaman önce) özellikle :=atama operatörü ( ==eşitlik testi için) yaptığımız bir dil tasarlarken hatırlıyorum .
Donal Fellows

7
Çok, çok sayıda kod satırı yazdım ve hiçbir zaman yanlışlıkla yazmak =yerine yazmadım ==. Aradaki fark o kadar belirgindir ki, kafamı hiç karışmadı. Öte yandan, kafa karıştırıcı ya da anlaşılması zor olan birçok kod parçası okudum. Bu nedenle, öncelikleri okunabilirlik üzerine koyardım :). Ne olursa olsun, iyi cevap.
crazy2be

5
Bir başka iyi sebep kullanmak için -Wall -Werrorya da derleyici / tercüman eşdeğeri. Bir koşul içinde yapılan bir ödevin doğru olduğu, daha okunabilir bir durumda olduğu çok az durum vardır. Pek çok dil buna izin bile vermiyor.
Karl Bielefeldt

7
Bilgiçlik: iken if($foo = 1)için değerlendirir truebazı dillerde, PHP'de yerine 1 olarak değerlendirilir; if($foo = 20)20 olarak değerlendirir; if($foo = 0)diğerlerinden farklı olarak yanlış olan 0 olarak değerlendirilir. Bu, hataya bir bütün 'başka bir karmaşıklık katmanı ekleyebilir.
Charles

2
Aslında, WordPress Kodlama Standartları Yoda Koşullularını çağırıyor
Tom Auger

13

Atama operatörünün yanlışlıkla kullanılmasını önleme amaçlı bir savunma kodlama mekanizmasıdır.

Eşitlik operatörünün yerine atama operatörünün kötüye / yanlış olduğunu düşünün

if ( $options['postlink'] = 1  )

Yukarıdaki şartlar her zaman doğrudur, ancak muhtemelen orijinal programcının aklında olan şey bu değildi. Bir yerde, bu düşünün

if( 1 = $options['postlink'])

Burada, PHP (ve diğer birçok dil) çalışmasını reddeder, çünkü sabit değerine bir şey atamak imkansızdır 1. Tüm koşullu ifadeleri bu şekilde kodlayarak, bir atama operatörünün koşullu olarak yanlışlıkla kullanılmamasını otomatik olarak sağlarsınız.


9

Boş bir işaretçi istisnası olasılığını ortadan kaldırmak için java'daki bu sözleşmeyi kullanmayı seviyorum. Böylece böyle bir şey size herhangi bir sorun yaratmayacak veya herhangi bir ekstra kod gerekmeyecektir:

String foo = null;

if ("bar".equals(foo))
{
    //Do something
}

3
Bunu sevdim ama genel deyimden nefret ediyorum.
Thomas Eding

3
Eğer boş bir değer koddaki o noktaya göre geçerli değilse, zaten zaten kontrol etmiş ya da kodunuzu boş bir değerin imkansız olacağı şekilde tasarlamış olmalısınız.
Ed S.,

6
bu problemleri maskelemek için kolay bir yol gibi görünüyor. Tozlar halının içinde shrugging ile temizlenmez.
Lie Ryan

0

Uygulamada, birçok derleyici size "if (x == 1)" yerine "if (x = 1)" yazarsanız bir uyarı verecektir çünkü bu büyük olasılıkla bir hatadır.

Clang ile derleyiciye "Bunu kast ediyorum ve ne yaptığımı biliyorum" diyerek uyarıdan kaçınabilirsiniz ve bu "if ((x = 1))" yazarak yapılır. Ekstra parantezleri not alın. Bu diğer durumlarda da işe yarıyor. if (false) ifadesi; ifadenin asla yürütülmediğine dair bir uyarı verebilir; if ((false)) ifadesi; bu uyarıyı vermez.


Bunu çok beğendim! Aşağıdakilerden kaçınıyorum, PHP'de tamamen okunaklı deyim çünkü IDE'mde daima uyarılarım var:if ($array = getSomething()){ // ..so something with $array }
Tom Auger
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.