2010-05-22 109 views
3

我试图在PHP中使用OOP构建网站。每个人都在谈论辛格尔顿,诠释,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(); 
} 

我不像那些异常处理程序 - 我不想像一些小宠物一样抓住它们...我想用简单的东西: $ core-> theme-> display('footer'); 如果有问题,并且调试模式已启用,则应用程序显示错误。我该怎么办?

回答

1

我不熟悉PHP,但你应该明确停止做小宠物的例外。首先,不应该用特定的异常(CoreException)替换每个异常(PDOException)。其次,使用多个catch块在使用部分,如:

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

你的类“核心”就可以压缩下来相当(没有更多的try/catch每个项目)。当然,你会在更高的层次上显示更多的catch块,但这就是你应该用OOP和异常做的事情。

最后,检查是否已经存在一个异常超类,用于您尝试捕获的某些异常子集。这将减少catch块的数量。

+0

嗯,我刚刚开始,但这种多重捕捉缩短了我的代码!我已经使用了CoreException,因为我不知道这个多重捕获 – Misiur 2010-05-22 14:57:33

1

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

这样做

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

另外,也可以代替throw errors,然后调整error_reporting水平。

+0

它是唯一的方式吗?然后,我仍然不得不在尝试调试之后尝试/捕获错误。 – Misiur 2010-05-22 14:43:37

+0

如果打开了调试,您可以让异常处理并修复错误。 – Artefacto 2010-05-22 14:53:31

1

您可以考虑使用自定义错误处理程序并将其设置为应用程序范围。如果您正在像前端控制器这样的设计模式下操作,这个处理程序可以很容易地在应用程序范围内设置,这只是一个真正有效的方法

这里是处理我通常使用的一个例子:

<?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', '[email protected]'); 
define('SENDMAIL_FROM', '[email protected]'); 


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