Neden ve nasıl bu örnek PHP kodu İstisnalar kullanmak istiyorsunuz?

4 Cevap php

Ben PHP İstisnalar kullanmak neden merak ettik. Basit bir örneğe bir göz atalım:

class Worker
{
 public function goToWork()
 {
  return $isInThatMood ?
  // Okay, I'll do it.
  true : 
  // In your dreams...
  false;
 }
}

$worker = new Worker;
if (!$worker->goToWork())
{
 if (date('l',time()) == 'Sunday')
  echo "Fine, you don't have to work on Sundays...";
 else
  echo "Get your a** back to work!";
}
else
 echo "Good.";

Bana kod için bu tür İstisnalar kullanmak için bir sebep var mı? Neden? Nasıl kod inşa edilecekti?

Ve hataları kod hakkında ne üretebilir ki:

class FileOutputter
{
 public function outputFile($file)
 {
  if (!file_exists($file))
   return false;
  return file_get_contents($file);
 }
}

Neden yukarıdaki durumda İstisnalar kullanmak istiyorsunuz? Ben bir İstisnaları, gerçek meydana sorunun türünü tanımak için yardımcı duygu var?

Yani, ben bu kodu uygun İstisnalar kullanıyorum:

class FileOutputter
{
 public function outputFile($file)
 {
  if (!file_exists($file))
   return throw new Exception("File not found.",123);
  try
  {
   $contents = file_get_contents($file);
  }
  catch (Exception $e)
  {
   return $e;
  }
  return $contents;
 }
}

Yoksa bu yoksul? Şimdi yatan kod yapabilirsiniz:

$fo = new FileOutputter;
try
{
 $fo->outputFile("File.extension");
}
catch (Exception $e)
{
 // Something happened, we could either display the error/problem directly
 echo $e->getMessage();
 // Or use the info to make alternative execution flows
 if ($e->getCode() == 123) // The one we specified earlier
  // Do something else now, create "an exception"
}

Ya da ben tamamen burada kaybettim ben?

4 Cevap

When should I use an exception?

Bir exceptional durumunu belirtmek için bir istisna kullanın; O, onun sözleşme yerine bir yöntemi engelleyen bir şeydir, ve bu düzeyde meydana olmamalıdır hangi.

Örneğin, bir veritabanına bir kayda değişiklikleri kaydeder ki, Record::save(), bir yöntem olabilir. , Nedense, bu (örneğin, bir veritabanı hatası oluştuğunda veya bir veri kısıtlama kırık) yapılamaz, o zaman başarısızlık belirtmek için bir istisna olabilir.

How do I create custom exceptions?

Özel durumlar genellikle, örneğin, hata doğasını gösterir, DatabaseException şekilde adlandırılır. Siz, örneğin, Exception bu şekilde adlı özel durumlar oluşturmak için alt sınıf

class DatabaseException extends Exception {}

(Tabii ki, bu istisna örneğin bağlantı ayrıntılar ya da bir veritabanı hata kodu gibi bazı ek tanı bilgileri, vermek miras yararlanabilir.)

When shouldn't I use an exception?

Bir başka örnek düşünün; dosya varlığını kontrol eden bir yöntem. Dosya yoksa yöntemin amacı gerçekleştirmek beri bu muhtemelen not, bir istisna gerektiğini onay söyledi. Ancak, dosyayı açar ve bazı işleme dosya var bekleniyordu beri could, bir istisna, vb gerçekleştiren bir yöntem

Bir şeydir ve istisnai değil Başlangıçta, her zaman açık değil. Sen ve bir istisna değil gerektiğine ne zaman çoğu şey gibi, tecrübe, zamanla, size öğretecektir.

Why use exceptions instead of returning special error codes, etc?

İstisnalar hakkında yararlı şey hemen geçerli yöntem fırlamış ve onlar yakaladı ve ele konum kadar ideal, çok yüksek olmamakla birlikte, daha yüksek hata işleme mantığı yukarı taşımak anlamına gelir, çağrı yığını baş yukarı olmasıdır.

Kötü bir şey olduğunda başarısızlık davalarına net bir mekanizma kullanarak, otomatik olarak kontrol edilmesi gereken sihirli nöbetçi değerler, ya da daha kötüsü, bir genel hata bayrak her türlü ile ilgili önlemek anlamına gelir, hata işleme kodunu tekmelemek Farklı olasılıklar bir grup arasında ayırt etmek.

Ben bir PHP programcısı değilim, ama bu C # benzer.

Genellikle bunun dönüşü olmayan bir nokta ise hataları atmak isterdim. Sonra imkansız gerçekleştiğini göstermek için bir şey oturum açmak mümkün olacaktır.

Eğer dosya yoksa söyleyebilir, o zaman sadece söyleyebiliriz. Da bir özel durum için aklımda hiç gerçek gerek.

Dosya bulundu ve bunu işleme, ve sadece yarım dosya yüklenir ve siz bir istisnasız söylüyorum hiçbir şekilde vardı diyeceksin Şimdi eğer, o zaman etrafında olması güzel olurdu.

Ben önceki örnekte yapıyor gibi görünüyor gibi, bu catch tüm istisnalar "catch (Exception $ e)" ve bunun yerine sözleşme ile tasarım önlemek için iyi bir tasarım uygulama olduğunu söyleyebilirim. Ben de ilk istisna atılan türü ile daha spesifik olması ve daha sonra gerekirse oradan çalışacak. Aksi takdirde, uzak deneyin-> yakalamak ve istisnalar muaftır.

In no way can you assume that a file exists just because you called file_exists() ! The function file_exists dosyayı açmaz, bu yüzden dosya potansiyel silinmiş veya yeniden adlandırılmış ya da herhangi bir zamanda taşınmış olabilir!

class FileOutputter
{
    public function outputFile($file)
    {
        if (!file_exists($file))
            return false;
        ///<--- file may be deleted right here without you knowing it
        return file_get_contents($file);//<-- then this will throw an error
            //if you don't catch it, you're program may halt.
    }
}

Ben bu daha iyi inanıyorum:

class FileOutputter
{
    public function outputFile($file)
    {
        try{
            if (!file_exists($file))
                return false;
            return file_get_contents($file);
        }catch(Exception e){
            check_what_went_wrong_and_go_to_plan_B();
        }
    }
}

(Edit: Ve aslında başından itibaren dosyayı açmaya çalıştığınızda muhtemelen daha iyidir Bundan sonra eğer dosya üzerinde bir 'kilit' var ve sadece yok olmayacak değilse o başarılı olursa.. durum yakalamak ve neyin yanlış gittiğini görüyoruz.

Sonra tekrar, devşirim bu düzeyde sadece aptalca olduğunu hissedebilirsiniz. Bu durumda ben hepiniz :) at try/catch endişelenmenize gerek olduğunu sanmıyorum

Just a note really, your code for file outputter is invalid, since file_get_contents($file) does not throw an exception. It will however raise a warning if the file doesn't exist, or can't be accessed for some reason. Additionally, you are returning an exception from outputFile, when you should probably be just letting the error propagate up the call stack.

Ancak, bir hata oluştuğunda istisnalar atmak için php hata işleyicisi kayıt olabilirsiniz:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");

Bu şekilde, bir hata neden herhangi bir standart fonksiyon çağrıları bir istisna atar.

Yani, (eklendi yukarıda ki pasajı ile) bu FileOutputter değiştirmek istiyorsunuz:

class FileOutputter
{
 public function outputFile($file)
 {
  if (!file_exists($file))
   throw new Exception("File not found.",123);

   return file_get_contents($file);  
 }
}

Çağrı kodunun ardından temelde aynıdır.

Temelde bir hata oluştuğunda, bir özel durum dönmek için değil kural - Eğer isterseniz onu yakalamak, ve özel bir istisna, ama bunu kullanmak istediğiniz kadar durum çağrı yığını gidelim.