PHP Hata işleme

9 Cevap php

Ben bazı temel aşina değilim, ama ne zaman ve neden (özel durumlar atma dahil) işleme hatası PHP kullanılması gerektiğini ne hakkında daha fazla bilmek istiyorum, özellikle canlı bir site veya web uygulaması vardır. Bu gereksiz bir şeydir ve eğer öyleyse, ne aşırı benziyor? Bu kullanılmamalıdır durumlar var mı? Ayrıca, konuda ortak güvenlik kaygıları bazı hata işleme nelerdir?

9 Cevap

Zaten söylenenleri eklemek için bir şey, bir günlüğüne web uygulamasında herhangi bir hata kaydetmek buyük önem olmasıdır. Bu şekilde, Jeff "Kodlama Horror" Atwood kullanıcıların (yerine "Sorunun ne olduğunu soran") sizin uygulaması ile sorun yaşıyorsanız, ne zaman bileceksiniz, göstermektedir.

Bunu yapmak için, ben altyapının şu tür tavsiye:

  • Veritabanı ve hataları raporlama için sarıcı sınıflar seti bir "kaza" bir tablo oluşturun. Ben (vs, vs hariç, "PHP hata / uyarı" (), "güvenlik", "engelleme") çöker kategoriler ayarını öneriyoruz.
  • Hata işleme kodunun tüm, hatayı kaydetmek için emin olun. Bunu yapmak sürekli size (adım yukarıda) API inşa ne kadar iyi bağlıdır - doğru yapılırsa trivial çöküyor kaydetmek olmalıdır.

İlave kredi: bazen, senin çöküyor veritabanı düzeyinde çöküyor olacak: Bu durumda ise, hata günlüğü altyapı (üstte) DB kazasında oturum açamıyor (başarısız olur yani DB sunucu aşağı, vb günlük çalışır çünkü ) DB yazmak için. Bu durumda, ben senin Crash sarıcı sınıfında başarısızlık mantığı yazarsınız ya

  • admin bir e-posta göndermek, VE / VEYA
  • bir düz metin dosyasına çökmesi ayrıntılarını kayıt

Tüm bu bir overkill gibi geliyor, ama inan bana, bu uygulama bir "istikrarlı" ya da "lapa lapa" olarak kabul edilip bir fark yaratıyor. Bu fark tüm uygulamalar her zaman çökmesini / gibi lapa lapa başlar, ama bunların uygulaması tüm konular hakkında bilmek bu geliştiricilerin aslında bunu düzeltmek için bir şans olduğu gerçeği geliyor.

Istisnalar hatalarını tedavi etmek için modern bir yol ise Kabaca hataları, PHP bir miras. Basit şey, sonra bir istisna atar bir hata işleyicisi, kurmaktır. Bu şekilde tüm hataları istisnalar dönüştürülür, ve o zaman sadece bir hata işleme düzeni ile başa çıkabilirim. Aşağıdaki kodu sizin için istisnalar hataları dönüştürür:

function exceptions_error_handler($severity, $message, $filename, $lineno) {
  if (error_reporting() == 0) {
    return;
  }
  if (error_reporting() & $severity) {
    throw new ErrorException($message, 0, $severity, $filename, $lineno);
  }
}
set_error_handler('exceptions_error_handler');
error_reporting(E_ALL ^ E_STRICT);

Kod özellikle hataları ile çalışmak üzere tasarlanmış olduğu birkaç olgu olsa vardır. Örneğin, DomDocument raises warnings, when validating a document. If you convert errors to exceptions, it will stop validating after the first failure. Some times this is what you want, but when validating a document, you might actually want all başarısızlık schemaValidate yöntemi. Bu durumda, geçici hataları toplayan bir hata işleyicisi, yükleyebilirsiniz. İşte bu amaçla kullandım küçük bir parçasını, bulunuyor:

class errorhandler_LoggingCaller {
  protected $errors = array();
  function call($callback, $arguments = array()) {
    set_error_handler(array($this, "onError"));
    $orig_error_reporting = error_reporting(E_ALL);
    try {
      $result = call_user_func_array($callback, $arguments);
    } catch (Exception $ex) {
      restore_error_handler();
      error_reporting($orig_error_reporting);
      throw $ex;
    }
    restore_error_handler();
    error_reporting($orig_error_reporting);
    return $result;
  }
  function onError($severity, $message, $file = null, $line = null) {
    $this->errors[] = $message;
  }
  function getErrors() {
    return $this->errors;
  }
  function hasErrors() {
    return count($this->errors) > 0;
  }
}

Ve kullanımı durum:

$doc = new DomDocument();
$doc->load($xml_filename);
$validation = new errorhandler_LoggingCaller();
$validation->call(
  array($doc, 'schemaValidate'),
  array($xsd_filename));
if ($validation->hasErrors()) {
  var_dump($validation->getErrors());
}

Unhanded hataları tek başına bunları işlemek için oldukça iyi bir neden olduğunu, senaryoyu durdurun.

Genellikle hataları ile uğraşmak için bir Try-Catch bloğunu kullanabilirsiniz

try
{
    // Code that may error
}
catch (Exception $e)
{
    // Do other stuff if there's an error
}

Eğer hata ya da sayfada görünen uyarı mesajı durdurmak istiyorsanız, o zaman şöyle bir @ işareti ile arama öneki.

 @mysql_query($query);

Sorgu ile ancak genellikle oluyor ne daha iyi bir fikrim yok yani böyle bir şey yapmak için iyi bir fikirdir.

@mysql_query($query)
    or die('Invalid query: ' . mysql_error() . '<br />Line: ' . __LINE__ . '<br />File: ' . __FILE__ . '<br /><br />');

Eğer komut üzerinde çalışıyor veriler üzerinde kesin bir kontrol yok durumlarda Hata İşleme kullanmalısınız. Ben form doğrulama gibi yerlerde, örneğin sık sık kullanma eğiliminde. Kodda hata eğilimli yerlere nokta nasıl bilmek biraz pratik alır: Bazı yaygın olanları bir değer dönmek işlev çağrıları sonrasında, ya da bir veritabanı sorgu sonuçları ile uğraşırken. Bir fonksiyonun geri dönüş sizin bekliyor ne olacağını varsayabiliriz asla ve beklentisiyle kod emin olmalıdır. Onlar yararlı olsa, try / catch blokları kullanmak zorunda değilsiniz. Bir çok kez eğer / else kontrol basit bir ile alabilirsiniz.

Script sadece çökmesine neden olmaz "hataların" bir yeri vardır gibi hata işleme, güvenli kodlama uygulamaları ile el ele gider. başına hata işleme konusunda kesinlikle olmaması ise, addedbytes sen HERE bulabilirsiniz Güvenli PHP programlama temelleri bazı iyi 4 makale dizi var. Diğer bir çok soru Girilen verileri kullanıcı içeriğini doğrulayan çok güçlü olabilir gibi mysql_real_escape_string ve Regular Expressions gibi konularda stackoverflow burada bulunmaktadır.

The best practice IMHO is to use the following approach: 1. create an error/exception handler 2. start it upon the app start up 3. handle all your errors from inside there

<?php

class Debug {

    public static setAsErrorHandler() {
         set_error_handler(array(__CLASS__, '__error_handler'));
    }

public static function __error_handler($errcode, $errmsg, $errfile, $errline) {
       if (IN DEV) {
                print on screen
           }
           else if (IN PRO) {
                log and mail
           } 
    }

}

Debug :: setAsErrorHandler ();

>

Aksine mysql_error çıktılamak daha bir günlüğüne saklamak olabilir. Bu şekilde hata izleyebilirsiniz (ve bunu bildirmek için kullanıcılar bağlı olmayan) ve gitmek ve sorunu kaldırabilirsiniz.

En iyi hata işleme kod sıralamak izin, kullanıcı için saydamdır tür sorun, bu kullanıcı adam dahil etmek gerek.

kodunuzu hemen hataları işleme yanında da yararlanabilirler

http://us.php.net/manual/en/function.set-exception-handler.php
and
http://us.php.net/manual/en/function.set-error-handler.php

Ben özellikle yararlıdır kendi özel durum işleyicisi ayarını bulabilirsiniz. Bir istisna meydana geldiğinde o istisna türüne bağlı olarak farklı işlemleri gerçekleştirebilirsiniz.

ex: ne zaman mysql_connet çağrı döndürür FALSE bir new DBConnectionException(mysql_error()) atmak ve "özel" bir şekilde işlemek: hata oturum, DB bağlantı bilgileri (ev sahibi, Kullanıcı adınızı, şifrenizi vb) ve hatta belki de bir şey DB gerçekten yanlış olabileceğini bildiren dev ekibine e-posta

Ben standart hata işleme iltifat için kullanabilirsiniz. ben bu yaklaşımı overusing tavsiye etmem

@ Ile hata bastırma çok yavaş.

Ayrıca veritabanı veya kamuya açık bir sunucu korumak zorunda kalmadan, özel durumları yakalamak ve analiz etmek için Google Formlar kullanabilirsiniz. Sürecini açıklayan bir öğretici here vardır.