Soru PHP'de, neden “veya ölmek ()” çalışır, ama “ya da geri dönüş” olmaz?


PHP'de hataları arayarak hatalar üstesinden gelebilirsiniz or die gibi belirli hatalarla karşılaştığınızda çıkmak için:

$handle = fopen($location, "r") or die("Couldn't get handle");

kullanma die() hataları işlemek için harika bir yol değil. Bir hata kodunu döndürmeyi tercih ederim, böylece ebeveyn işlevi sadece senaryoyu tam olarak birakmak ve hatayı kullanıcıya göstermek yerine ne yapacağına karar verebilir.

Ancak, PHP değiştirmeye çalıştığımda bir hata gösteriyor or die ile or return, bunun gibi:

$handle = fopen($location, "r") or return 0;

Neden yapıyor or die() iş, ama değil or return 0?


18
2018-01-18 05:54


Menşei




Cevaplar:


Bu soruyu sorduğunuz için teşekkür etmek istiyorum, çünkü or return PHP'de. Test ettiğimde senin kadar şaşırdım. Bu soru bana biraz araştırma yapmak ve PHP'nin içlerinde oynamak için iyi bir bahane verdi. Ancak, ben PHP'nin internals uzmanı değilim, bu yüzden oldukça doğru olduğunu düşünüyorum rağmen, aşağıdaki PHP stantları bir layman'ın görünümüdür.


or return çalışmıyor çünkü return Dil ayrıştırıcısı tarafından bir "ifade" kabul edilmez - bu kadar basit.

Anahtar kelime or PHP dilinde çağrılan bir simge olarak tanımlanır T_LOGICAL_ORve tanımlanmış gibi görünüyor tek ifade gibi görünüyor bu:

 expr T_LOGICAL_OR { zend_do_boolean_or_begin(&$1, &$2 TSRMLS_CC); } expr { zend_do_boolean_or_end(&$$, &$1, &$4, &$2 TSRMLS_CC); }

Diş teli içindeki bitler için endişe etme - sadece gerçek "veya" mantığının nasıl işlendiğini tanımlar. Ne ile kalıyorsun? expr T_LOGICAL_OR exprSadece bir ifade için geçerli bir ifade olduğunu söyleyen T_LOGICAL_OR belirteci, ardından başka bir ifade.

bir expr ayrıca beklediğiniz gibi ayrıştırıcı tarafından tanımlanır. Ya bir olabilir r_variableBu sadece okunmasına izin verilen bir değişken olduğu anlamına gelir. expr_without_variableBu, bir ifadenin diğer ifadelerden yapılabileceğini söyleyen süslü bir yoldur.

Yapabilirsin or die() çünkü dil kurgusu die (bir işlev değil!) ve diğer adı exit her ikisi de simge tarafından temsil edilir T_EXIT, ve T_EXIT geçerli kabul edilir expr_without_variable, oysa return ifade - belirteç T_RETURN - değil.

Şimdi neden T_EXIT bir ifade olarak kabul edildi ama T_RETURN değil? Dürüst olmak gerekirse, hiçbir fikrim yok. Belki de sadece izin vermek için yapılmış bir tasarım seçimdi or die() sorduğun şeyi inşa et. Yaygın olarak kullanılan bir şey - en azından öğreticiler gibi şeyler, çünkü büyük miktarda üretim koduyla konuşamıyorum - bunun kasıtlı bir seçim olabileceğini ima ediyor. Dil geliştiricilerinden emin olmalarını istemeniz gerekir.


Bütün bunlarla birlikte, bunun önemi yok. İken or die() Yapı, birkaç yıl önce öğreticilerde (yukarıya bakınız) her yerde göründü, gerçekten tavsiye edilmez, çünkü bu “akıllı kod” örneğidir. or die() kendi başına bir yapı değil, daha çok kullandığı bir hiledir - bazıları kötüye kullanım olabilir - iki yan etki or Şebeke:

  • Operatör önceliği listesinde çok düşüktür, diğer bir deyişle, hemen hemen tüm diğer ifadeler değerlendirilmeden önce değerlendirilecektir.
  • Bu kısa devirli bir operatördür, yani ikinci işlenen (bittikten sonra orİlk işlenen döndürürse) yürütülmez TRUEÇünkü bir işlenen ise TRUE içinde or İfade, sonra ikisi de vardır.

Bazı insanlar bu tür bir aldatmacanın elverişsiz olduğunu düşünürler, çünkü bir programcının okuması daha zor olduğundan kaynak kodda sadece birkaç karakter alanı kaydeder. Programcı zamanı pahalı olduğundan ve disk alanı ucuz olduğundan, insanların neden bundan hoşlanmadığını görebilirsiniz.

Bunun yerine, kodunuzu tam teşekküllü bir şekilde genişleterek niyetinizle açık olmalısınız. if Beyan:

$handle = fopen($location, "r");
if ($handle) {
  // process the file
} else {
  return 0;
}

Değişken atamalarını doğrudan if Beyan. Bazı insanlar hala bu okunaksız buluyor, ancak çoğu insan (dahil) katılmıyorum:

if ($handle = fopen($location, "r")) {
  // process the file
} else {
  return 0;
}

Son bir şey: geri dönen bir konudur 0 bir durum kodu olarak başarıyı gösterir, bu yüzden dosyayı açamadığınızı belirtmek için farklı bir değer vermek isteyebilirsiniz.


25
2018-01-18 07:43



Bu komik şey ... Dönüş bir dil yapısı ve OP tarafından istenen şekilde kullanılamaz. Buna karşılık ölmek ayrıca bir dil yapısı ama yine de yukarıda istenen yöntemde kullanılabilir. Oysa ölmek için bir takma addır çıkış Kullanılabilecek başka bir dil yapısı. Geri dönüş bu gruptaki garip olanı. - Mark Tomlin
@MarkTomlin Ben düşünmüyorum return Burada garip olanı. return bir ifadedir ve böyle tanımlanmıştır (özellikle unticked_statementgibi diğer ifadelerle birlikte if ve foreach. Bu gruba açıkça uyuyor. Emin değilim neden exit bir ifade olarak kabul edilir, çünkü bir değişkene atamak işlevi çağırır ve betiği öldürür. Ayrıca exit boş bir işlevdir, bu yüzden sadece atamanız gerekir NULL yardımcı olmayan değişkene. Gerçekten sadece izin vermek için bir ifade olarak düşündüğünü düşünüyorum or die() çalışmak için inşa etmek. Tuhaf. - AgentConundrum
+1 büyük cevap, benim için birkaç şeyi açıklığa kavuşturdu :) - andr


Bunun üzerine bir kez de rastladım. Tek bulabildiğim şuydu:

https://bugs.php.net/bug.php?id=40712

Aşağıdaki yoruma bakın:

bu bir hata değil

Dokümanlarda arama yaptım ve bunun sebebi olduğunu düşünüyorum. return 0 bir açıklamadır die() aslında bir ifadedir. Koşamazsın $handle = return 0; fakat $handle = fun(); geçerli kod.

Hata işleme ile ilgili olarak, özel kodları veya özel işleyicileri ve tetikleyicileri kullanmanızı öneririm. İkincisi burada tarif Örneğin.


0
2018-01-18 06:11





Dönüş oldukça özeldir - fonksiyonlardan çıkmak için bir araç olduğu için işlev gibi bir şey olamaz. Bunu hayal et:

if(1==1) return();  // say what??

Böyle olsaydı, dönüş sadece kendi kapsamını değil, arayanı da bırakan bir "çifte çıkış" yapan bir işlev olmalıydı. Dolayısıyla geri dönüş bir ifade gibi bir şey değildir, sadece bu şekilde çalışamaz.

Şimdi, teoride, geri dönüş, yanlış (ve) olarak değerlendiren bir ifade olabilir. sonra işlevden çıkar; Belki sonraki bir php sürümü bunu uygular.

Aynı şey için de geçerlidir git bir geri çekilme olarak çalışmak için bir cazibe olurdu; ve evet, geri dönüşler gereklidir ve çoğu zaman kodun okunabilir olmasını sağlar, bu nedenle eğer birisi "akıllı kod" dan şikayet ederse (ki bu kesinlikle iyi bir nokta) belki de php böyle bir şeyi yapmanın bazı "resmi" yollarına sahip olmalıdır:

connectMyDB() fallback return false;

Denemek gibi bir şey ... yakalama, sadece daha fazla noktaya. Ve kişisel olarak, İngilizce dilbilgisi ile iyi çalıştığı için bu işi "veya" yaparak "çok daha mutlu olurdum": "bağlan veya rapor hatası".

TLDR: kesinlikle haklısın: dönüş, git, ara ver - hiçbiri işe yaramaz. Nedenini anlamak kolay ama yine de can sıkıcı.


0
2018-01-15 15:55