我正在尝试使用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;显示器( '页脚'); 如果出现问题,并且启用了调试模式,则应用程序显示错误。我该怎么办?
答案 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>');