PHP nasıl yanlış türünü kullanarak engellerim?

7 Cevap php

PHP, hepimizin bildiği gibi çok gevşek yazdınız. Dil fonksiyon parametreleri ya da sınıf değişkenleri için türü her türlü belirtmenizi gerektirmez. Bu güçlü bir özellik olabilir.

Bazen de, bu sizin komut acı bir deneyim hata ayıklama yapabilirsiniz. Örneğin, nesnenin farklı bir tür beklediği bir yönteme nesnenin bir tür geçirerek belirli bir değişken / metod geçti nesne yok şikayet hata mesajları üretebilir. Bu durumlar çoğunlukla can sıkma vardır. Eğer "yanlış nesne", daha sonra komut dosyasının yürütülmesine kadar kullanılmayacaktır yanlış sınıfın bir nesne ile bir nesneyi başlatmak ve o zaman daha zahmetli sorunlardır. Bu durumda size çok daha sonra orijinal argümanı geçtiğinde daha bir hata alıyorum sonunda.

Bunun yerine ne geçti, belirli bir yöntem veya değişken olmadığını şikayet, veya daha sonra komut dosyası yürütme benim kullanılacak nesne geçti, I would much rather have an error message, at exactly where I specify an object of the wrong type, complaining about the object's type being incorrect or incompatible. kadar bekliyor

Nasıl kodunuzda bu durumlar ele? Nasıl uyumsuz türleri tespit ediyorsunuz? Nasıl bazı tip-kontrol alabilirim ki benim komut içine daha kolay anlaşılır hata mesajları tanıtabilirsiniz?

Ayrıca, tüm bu süre Php miras için muhasebe nasıl yapabilirim? Düşünün:

<?php
class InterfaceClass
{
#...
}

class UsesInterfaceClass
{
   function SetObject(&$obj) 
   {
       // What do I put here to make sure that $obj either
       // is of type InterfaceObject or inherits from it       

   }
}
?>

Sonra bu kodu bir kullanıcının kendi beton sınıfı ile arabirimini uygular:

<?php

class ConcreteClass extends InterfaceClass
{
}



?>

Ben de SetObject için kabul edilebilir ConcreteClass örneklerini ve tüm gelecek, bilinmeyen kullanıcı-tanımlı nesneler istiyorum. Nasıl doğru türü için denetlenirken bu izin verilebilir yapmak istiyorsunuz?

7 Cevap

Aslında sınıflar için PHP (5 +) tip katkısını sağlayabilir.

 <?php
 class UsesBaseClass
 {
      function SetObject(InterfaceObject $obj) 
      {
      }
 }
 ?>

Eğer beklediğiniz gibi bu da miras ile düzgün çalışacak.

Olarak bir kenara, sınıf adlarında kelime 'nesne' koymuyorsun ...

değil belli bir sınıfın sadece nesneleri - Eran Galperin cevabına ek olarak aynı zamanda diziler parametreleri zorlamak için Tür Dayatma kullanabilirsiniz.

<?php
class MyCoolClass {
   public function passMeAnArray(array $array = array()) {
      // do something with the array  
   }  
 }  
 ?>

Gördüğünüz gibi yöntem w / herhangi bir parametre o denir ::passMeAnArray() yöntemi beklediğini ipucu yazın bir array yanı sıra durumda varsayılan değer sağlayabilir.

Ilkel türleri için de is_ * işlevleri kullanabilirsiniz:

public function Add($a, $b)
{
  if (!is_int($a) || !is_int($b))
    throw new InvalidArgumentException();
  return $a + $b;
}

Sen type hinting. Bu teknik çözüm konusunda birden fazla cevaplar vardır, bkz. Ama aynı zamanda tüm tasarım mantıklı ve sezgisel olduğundan emin olmalısınız. Bu tür sorunlar ve hatalar daha nadir yapacaktır.

Hatta bu tip başarısızlıklar atılmış olacaktır unutmayın at runtime. Eğer kodu için testler olduğundan emin olun.

Hatta açıklamak durumunda, script bu nereden geliyor bilirsiniz böylece nesne Y üzerinde hiçbir yöntem / nitelik X olduğundan şikayet, çökmesine sebep olacaktır.

Yerine belgeleyen ve eğitim onu ​​harcayabilirsiniz: Her neyse, ben her zaman iyi bir zaman bir yatırım değil, bir yöntem yanlış bir nesne geçmek için programcılar büyüdü önlemek için deneyin düşünüyorum.

Yazarak ördek ve dikkatli arkadaşları size daha sert app yapacak ek denetimler değil, ihtiyacımız olan budur.

Ama bu bir görüş Pythonista noktası olabilir ...

@ Eran Galperin 'tepkisi kullandığınız nesne doğru türde olup sağlamak için tercih edilen bir yöntemdir.

Ayrıca fazlalaştı instanceOf operatörü - Eğer bir nesne birden fazla türde biri olduğunu kontrol etmek istediğiniz zaman için yararlıdır.

Php.ini dosyasında ayarlama ini error_reporting ayarlamak veya çalışma zamanında bunu ayarlamak için error_reporting işlevini kullanabilirsiniz