Php 在带有autoloader的errorhandler中使用MySQLi扩展类
我在PHP中使用以下组合时遇到了一个问题:Php 在带有autoloader的errorhandler中使用MySQLi扩展类,php,mysql,class,error-handling,autoload,Php,Mysql,Class,Error Handling,Autoload,我在PHP中使用以下组合时遇到了一个问题: 一个自定义类加载器“classloader”,作为一个单例实现,并使用spl\U autoload\U寄存器注册,它只需要\U一次就可以包含这些类。没什么特别的,只是一些在磁盘上组织类的路径 扩展mysqli类的数据库类“DB”。它是从目前只知道一个实例的工厂创建的。它只不过加载正确的配置并提供一些快捷方式 一个自定义的errorhandler“errorhandler”,作为一个单例实现,它使用DB类将通知和警告记录到数据库中 所有这些都很好;c
- 一个自定义类加载器“classloader”,作为一个单例实现,并使用spl\U autoload\U寄存器注册,它只需要\U一次就可以包含这些类。没什么特别的,只是一些在磁盘上组织类的路径
- 扩展mysqli类的数据库类“DB”。它是从目前只知道一个实例的工厂创建的。它只不过加载正确的配置并提供一些快捷方式
- 一个自定义的errorhandler“errorhandler”,作为一个单例实现,它使用DB类将通知和警告记录到数据库中
- 不要在我的“DB”类中扩展mysqli类;这使得它不起作用,但似乎表明扩展mysqli导致了问题
- 全局自动加载我自己的“DB”类,或者在ErrorHandler.php类文件的顶部自动加载
- 在获取ErrorHandler类中的实例之前,使用require_显式地加载“DB”类一次
class ClassLoader {
private $_paths = array();
private function __construct() {
// ... bunch of $this->append() calls with all paths and 3rd party libs
}
private static $_instance = null;
public static function get() {
if (self::$_instance === null) {
self::$_instance = new self();
}
return self::$_instance;
}
public function append($path, $format = '$.class.php') {
if (!array_key_exists($path, $this->_paths)) {
$this->_paths[$path] = $format;
return true;
}
return false;
}
public function autoload($class_name) {
foreach ($this->_paths as $path => $format) {
$file = $path.'/'.str_replace('$', $class_name, $format);
if (file_exists($file)) {
require_once($file);
return true;
}
}
return false;
}
}
$autoloader = ClassLoader::get();
$autoloader->append(dirname(__FILE__).'/classes');
spl_autoload_register(array($autoloader, 'autoload'));
数据库
Config是一个具有一些公共属性的单例
错误处理程序
class ErrorHandler extends Object {
/*
* Strip recursion problems in the backtrace
*/
private static function _filter_backtrace($array, $depth = 0) {
$result = array();
foreach ($array as $name => $value) {
switch (gettype($value)) {
case 'object':
case 'unknown type':
case 'resource':
break;
case 'array':
//$result[$name] = self::_filter_backtrace($value);
break;
default:
//$result[$name] = $value;
}
}
return $result;
}
private function _handle_db($errno, $errstr, $errfile, $errline, $backtrace) {
$db = DB::get(Config::get());
$db->dieOnError(true); // prevents infinite loops in error handler
// DB query here
$db->dieOnError(false); // for non-dying.
}
private function __construct() {
}
private static $_instance = null;
public static function get() {
if (self::$_instance === null) {
self::$_instance = new self();
}
return self::$_instance;
}
public function handle($errno, $errstr, $errfile, $errline) {
// No error? Return without reporting
if (!($errno & error_reporting())) {
return;
}
// Type of error
switch ($errno) {
case E_NOTICE:
case E_USER_NOTICE:
$errors = "Notice";
break;
case E_WARNING:
case E_USER_WARNING:
$errors = "Warning";
break;
case E_ERROR:
case E_USER_ERROR:
$errors = "Fatal Error";
break;
default:
$errors = "Unknown";
break;
}
//$backtrace = self::_filter_backtrace(array_shift(debug_backtrace()));
$backtrace = array();
switch (Config::get()->error_log) {
case 'db':
ErrorHandler::_handle_db($errno, $errstr, $errfile, $errline, $backtrace);
break;
default:
// Dump
if (ini_get("display_errors")) {
printf("<br />\n<b>%s</b>: %s in <b>%s</b> on line <b>%d</b><br /><br />\n", $errors, $errstr, $errfile, $errline);
}
// Log
if (ini_get('log_errors')) {
error_log(sprintf("PHP %s: %s in %s on line %d", $errors, $errstr, $errfile, $errline));
}
break;
}
// Exit/return strategy
switch ($errno) {
case E_ERROR:
case E_USER_ERROR:
die();
break;
}
return TRUE;
}
}
类ErrorHandler扩展对象{
/*
*回溯中的条带递归问题
*/
私有静态函数_filter_backtrace($array,$depth=0){
$result=array();
foreach($name=>$value的数组){
开关(gettype($value)){
案例“对象”:
案例“未知类型”:
案例“资源”:
打破
案例“数组”:
//$result[$name]=self:_filter\u backtrace($value);
打破
违约:
//$result[$name]=$value;
}
}
返回$result;
}
私有函数_handle_db($errno、$errstr、$errfile、$errline、$backtrace){
$db=db::get(Config::get());
$db->dieOnError(true);//防止错误处理程序中出现无限循环
//数据库查询在这里
$db->dieOnError(false);//表示未死亡。
}
私有函数_u构造(){
}
私有静态$\u实例=null;
公共静态函数get(){
if(self::$\u实例===null){
self::$\u实例=新self();
}
返回self::$\u实例;
}
公共函数句柄($errno、$errstr、$errfile、$errline){
//无错误?返回而不报告
如果(!($errno&error\u reporting())){
返回;
}
//错误类型
交换机($errno){
案件通知:
案例E_用户通知:
$errors=“通知”;
打破
案例E_警告:
案例E_用户_警告:
$errors=“Warning”;
打破
案例E_错误:
案例E_用户_错误:
$errors=“致命错误”;
打破
违约:
$errors=“未知”;
打破
}
//$backtrace=self::_filter_backtrace(数组_移位(debug_backtrace());
$backtrace=array();
开关(配置::get()->错误日志){
案例“db”:
ErrorHandler::_handle_db($errno、$errstr、$errfile、$errline、$backtrace);
打破
违约:
//倾倒
if(ini\u get(“显示错误”)){
printf(“
\n%s:%s在%s中的%d行上,$errors,$errstr,$errfile,$errline”);
}
//日志
if(ini\u get('log\u errors')){
错误日志(sprintf(“PHP%s:%s在%s中的第%d行,$errors,$errstr,$errfile,$errline));
}
打破
}
//退出/返回策略
交换机($errno){
案例E_错误:
案例E_用户_错误:
模具();
打破
}
返回TRUE;
}
}
当数据库不可用时,您不能使用错误处理程序登录数据库
如果在初始化数据库之前调用错误处理程序,则会出现这种情况
您需要为这种情况实施回退。错误处理程序可以创建数据库,或者您需要先创建数据库,或者在这种情况下登录到文件,因为文件通常是可用的
在任何情况下调试你的问题都要考虑使错误登录到一个错误日志(PHP已经提供了,只是配置它),然后你<强>遗嘱< /强>当你触发这个问题时,找出你的具体问题是什么,它会给你更多的信息来更好地解决你的问题。(例如,删除记录器和数据库之间依赖关系中的缺陷).
我不确定这是否与您的问题有关。我看到一个发送到服务器的请求没有响应,这意味着响应中没有标题或正文。如果我没有记错,那是因为服务器超时。现在,我不记得这是在哪里发生的,但我需要它class ErrorHandler extends Object {
/*
* Strip recursion problems in the backtrace
*/
private static function _filter_backtrace($array, $depth = 0) {
$result = array();
foreach ($array as $name => $value) {
switch (gettype($value)) {
case 'object':
case 'unknown type':
case 'resource':
break;
case 'array':
//$result[$name] = self::_filter_backtrace($value);
break;
default:
//$result[$name] = $value;
}
}
return $result;
}
private function _handle_db($errno, $errstr, $errfile, $errline, $backtrace) {
$db = DB::get(Config::get());
$db->dieOnError(true); // prevents infinite loops in error handler
// DB query here
$db->dieOnError(false); // for non-dying.
}
private function __construct() {
}
private static $_instance = null;
public static function get() {
if (self::$_instance === null) {
self::$_instance = new self();
}
return self::$_instance;
}
public function handle($errno, $errstr, $errfile, $errline) {
// No error? Return without reporting
if (!($errno & error_reporting())) {
return;
}
// Type of error
switch ($errno) {
case E_NOTICE:
case E_USER_NOTICE:
$errors = "Notice";
break;
case E_WARNING:
case E_USER_WARNING:
$errors = "Warning";
break;
case E_ERROR:
case E_USER_ERROR:
$errors = "Fatal Error";
break;
default:
$errors = "Unknown";
break;
}
//$backtrace = self::_filter_backtrace(array_shift(debug_backtrace()));
$backtrace = array();
switch (Config::get()->error_log) {
case 'db':
ErrorHandler::_handle_db($errno, $errstr, $errfile, $errline, $backtrace);
break;
default:
// Dump
if (ini_get("display_errors")) {
printf("<br />\n<b>%s</b>: %s in <b>%s</b> on line <b>%d</b><br /><br />\n", $errors, $errstr, $errfile, $errline);
}
// Log
if (ini_get('log_errors')) {
error_log(sprintf("PHP %s: %s in %s on line %d", $errors, $errstr, $errfile, $errline));
}
break;
}
// Exit/return strategy
switch ($errno) {
case E_ERROR:
case E_USER_ERROR:
die();
break;
}
return TRUE;
}
}