例外情况混乱

时间:2010-05-22 14:35:48

标签: php oop exception

我正在尝试使用PHP中的OOP构建网站。每个人都在谈论Singleton,hermetization,MVC和使用异常。所以我试着这样做:

建立整个网站的课程:

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() { }

}

班级管理主题

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';
        }
    }

}

用法:

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();
}

我不喜欢那些异常处理程序 - 我不想像一些小宠物一样抓住它们......我想用简单的东西:     $核 - &GT;主题 - &GT;显示器( '页脚'); 如果出现问题,并且启用了调试模式,则应用程序显示错误。我该怎么办?

3 个答案:

答案 0 :(得分:1)

如果您不想捕获并想要忽略它们,那么您也可以不抛出异常(实际上,没有其他选择 - 必须捕获异常或脚本执行将结束)。

执行类似

的操作
if (debug_is_on())
    throw new MyException(...);

或者,您可以改为throw errors,然后调整error_reporting级别。

答案 1 :(得分:1)

我不熟悉PHP,但你肯定会停止做口袋妖怪例外。首先,不需要用特定异常(CoreException)替换每个异常(PDOException)。其次,在您的使用部分中使用多个catch块,如下所示:

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

你的班级“核心”可以大大减少(每个项目不再尝试/捕获)。当然,您将在更高级别显示更多的catch块,但这就是您应该使用OOP和异常。

最后,检查您是否已经尝试捕获的异常子集的异常超类。这将减少捕获块的数量。

答案 2 :(得分:1)

您可以考虑使用自定义错误处理程序并将其设置为应用程序范围。如果您在Front Controller等设计模式下运行,那么这只是一种非常有效的方法,可以在应用程序范围内轻松设置处理程序。

以下是我通常使用的处理程序示例:

<?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;
    }
}
?>

然后,您可以定义一些简单的常量来确定一些基本行为。

//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>');