İstisnalar karışıklık

3 Cevap php

PHP OOP kullanılarak sitesi kurmak için çalışıyorum. Herkes Singleton, Rezervuarları kapama, MVC bahsediyoruz, ve istisnalar kullanıyor. Yani bu gibi bunu denedim:

Sınıf inşaat tüm site:

class Core
{
    public $is_core;
    public $theme;
    private $db;
    public $language;
    private $info;
    static private $instance;

    public function __construct($lang = 'eng', $theme = 'default')
    {
        if(!self::$instance)
        {
            try
            {
                $this->db = new sdb(DB_TYPE.':host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASS);
            }
            catch(PDOException $e)
            {
                throw new CoreException($e->getMessage());
            }
            try
            {
                $this->language = new Language($lang);
            }
            catch(LangException $e)
            {
                throw new CoreException($e->getMessage());
            }
            try
            {
                $this->theme = new Theme($theme);
            }
            catch(ThemeException $e)
            {
                throw new CoreException($e->getMessage());
            }
        }
        return self::$instance;
    }
    public function getSite($what)
    {
        return $this->language->getLang();
    }
    private function __clone() { }

}

Sınıf yönetim temalar

class Theme
{
    private $theme;
    public function __construct($name = 'default')
    {
        if(!is_dir("themes/$name"))
        {
            throw new ThemeException("Unable to load theme $name");
        }
        else
        {
            $this->theme = $name;
        }
    }
    public function getTheme()
    {
        return $this->theme;
    }
    public function display($part)
    {
        if(!is_file("themes/$this->theme/$part.php"))
        {
            throw new ThemeException("Unable to load theme part: themes/$this->theme/$part.php");
        }
        else
        {
            return 'So far so good';
        }
    }

}

Ve kullanımı:

error_reporting(E_ALL);

require_once('config.php');
require_once('functions.php');

try
{
    $core = new Core();
}
catch(CoreException $e)
{
    echo 'Core Exception: '.$e->getMessage();
}
echo $core->theme->getTheme();
echo "<br />";
echo $core->language->getLang();

try
{
    $core->theme->display('footer');
}
catch(ThemeException $e)
{
    echo $e->getMessage();
}

I don't like those exception handlers - i don't want to catch them like some pokemons... I want to use things simple: $core->theme->display('footer'); And if something is wrong, and debug mode is enabled, then aplication show error. What should i do?

3 Cevap

PHP ile aşina değilim, ama kesinlikle pokemon istisnaları yaparken durdurmak gerekir. Birincisi, belirli bir özel durum (CoreException) ile her özel durum (PDOException) değiştirmeye gerek olmamalıdır. İkincisi, bu gibi, kullanım bölümünde birden çok catch blokları kullanın:

try
{
   $core->theme->display('footer');
}
catch(ThemeException $e)
{
   echo $e->getMessage();
}
catch(PDOException $e)
{
   echo $e->getMessage();
}

Sizin sınıf "Çekirdek" sonra önemli ölçüde (her madde için artık try / catch) aşağı küçültebilirsiniz. Verilen, daha yüksek bir düzeyde daha fazla catch bloğu gösterecektir, ama bu OOP ve istisnalar ile yapıyor olması gereken budur.

Son olarak, zaten yakalamak için çalışıyoruz istisnalar bazı alt kümesi için bir istisna süper sınıf olup olmadığını görmek için kontrol edin. Bu catch blok sayısını azaltacaktır.

Yakalamak ve onları görmezden istediğiniz istemiyorsanız, o zaman sen de (- istisnalar yakalanmış olması veya komut dosyası yürütme sona erecek var aslında, hiçbir alternatif yoktur) istisnalar atmak yok olabilir.

Gibi bir şey yapmak

if (debug_is_on())
    throw new MyException(...);

Alternatif olarak, throw errors yerine ve ardından error_reporting düzeyini ayarlayabilirsiniz.

Bir özel hata işleyicisi kullanarak ve bunu uygulama geniş ayar düşünebiliriz. Eğer işleyici kolayca geniş bir uygulama olarak ayarlanabilir Ön Denetleyicisi gibi bir tasarım deseni altında çalışan varsa bu sadece gerçekten geçerli bir yaklaşımdır.

Burada genellikle kullanmak işleyicisi bir örnek:

<?php
class ErrorHandler
{
    // Private constructor to prevent direct creation of object
    private function __construct()
    {
    }

    /* Set user error-handler method to ErrorHandler::Handler method */
    public static function SetHandler($errTypes = ERROR_TYPES)
    {
        return set_error_handler(array ('ErrorHandler', 'Handler'), $errTypes);
    }

    // Error handler method
    public static function Handler($errNo, $errStr, $errFile, $errLine)
    {

        $backtrace = ErrorHandler::GetBacktrace(2);

        $error_message = "\nERRNO: $errNo\nTEXT: $errStr" .
                     "\nLOCATION: $errFile, line " .
                     "$errLine, at " . date('F j, Y, g:i a') .
                     "\nShowing backtrace:\n$backtrace\n\n";

        // Email the error details, in case SEND_ERROR_MAIL is true
        if (SEND_ERROR_MAIL == true)
        error_log($error_message, 1, ADMIN_ERROR_MAIL, "From: " .
        SENDMAIL_FROM . "\r\nTo: " . ADMIN_ERROR_MAIL);

        // Log the error, in case LOG_ERRORS is true
        if (LOG_ERRORS == true)
        error_log($error_message, 3, LOG_ERRORS_FILE);

        /* Warnings don't abort execution if IS_WARNING_FATAL is false
         E_NOTICE and E_USER_NOTICE errors don't abort execution */
        if (($errNo == E_WARNING && IS_WARNING_FATAL == false) ||
        ($errNo == E_NOTICE || $errNo == E_USER_NOTICE))
        // If the error is nonfatal ...
        {
            // Show message only if DEBUGGING is true
            if (DEBUGGING == true)
            echo '<div class="error_box"><pre>' . $error_message . '</pre></div>';
        }
        else
        // If error is fatal ...
        {
            // Show error message
            if (DEBUGGING == true)
            echo '<div class="error_box"><pre>'. $error_message . '</pre></div>';
            else
            echo SITE_GENERIC_ERROR_MESSAGE;

            // Stop processing the request
            exit();
        }
    }

    // Builds backtrace message
    public static function GetBacktrace($irrelevantFirstEntries)
    {
        $s = '';
        $MAXSTRLEN = 64;
        $trace_array = debug_backtrace();

        for ($i = 0; $i < $irrelevantFirstEntries; $i++)
        array_shift($trace_array);
        $tabs = sizeof($trace_array) - 1;

        foreach ($trace_array as $arr)
        {
            $tabs -= 1;
            if (isset ($arr['class']))
            $s .= $arr['class'] . '.';
            $args = array ();

            if (!empty ($arr['args']))
            foreach ($arr['args']as $v)
            {
                if (is_null($v))
                $args[] = 'null';
                elseif (is_array($v))
                $args[] = 'Array[' . sizeof($v) . ']';
                elseif (is_object($v))
                $args[] = 'Object: ' . get_class($v);
                elseif (is_bool($v))
                $args[] = $v ? 'true' : 'false';
                else
                {
                    $v = (string)@$v;
                    $str = htmlspecialchars(substr($v, 0, $MAXSTRLEN));
                    if (strlen($v) > $MAXSTRLEN)
                    $str .= '...';
                    $args[] = '"' . $str . '"';
                }
            }

            $s .= $arr['function'] . '(' . implode(', ', $args) . ')';
            $line = (isset ($arr['line']) ? $arr['line']: 'unknown');
            $file = (isset ($arr['file']) ? $arr['file']: 'unknown');
            $s .= sprintf(' # line %4d, file: %s', $line, $file);
            $s .= "\n";
        }

        return $s;
    }
}
?>

Daha sonra bazı temel davranışları belirlemek için birkaç kolay sabitler tanımlayabilirsiniz.

//determines if the application will fail on E_WARNING level errors.
define('IS_WARNING_FATAL', true);
//determines error message shown
define('DEBUGGING', true);
// The error types to be reported
define('ERROR_TYPES', E_ALL);

// Settings about mailing the error messages to admin
define('SEND_ERROR_MAIL', false);
define('ADMIN_ERROR_MAIL', 'Administrator@example.com');
define('SENDMAIL_FROM', 'Errors@example.com');


//Saves errors to a file when true
define('LOG_ERRORS', false);
define('LOG_ERRORS_FILE', 'path-to-error-log');
/* Generic error message to be displayed instead of debug info
 (when DEBUGGING is false) */
define('SITE_GENERIC_ERROR_MESSAGE', '<h1>An unknown error occurred!  Our webmaster has been notified.</h1>');