php 自动加载错误码类,php – 在自动加载器的错误处理程序中使用MySQLi扩展类

我遇到了在

PHP中使用以下组合的问题:

>自定义类加载器“ClassLoader”,实现为单例并在spl_autoload_register中注册,它执行require_once以包含类.没什么特别的,只是在磁盘上组织类的一些路径.

>扩展mysqli类的数据库类“DB”.它是从一个目前只知道一个实例的工厂创建的.它只是加载正确的配置并提供一些快捷方法.

>自定义错误处理程序“ErrorHandler”,实现为单例,使用DB类将通知和警告记录到数据库.

所有这一切都很好;类加载器加载类,DB类正确执行查询,错误处理程序记录数据库中的错误.

…除非在调用任何数据库操作之前发生错误.

在这种情况下,PHP崩溃并崩溃;没有错误消息或任何东西,甚至没有任何echo或var_dump,甚至没有4xx或5xx代码.

浏览器只报告没有收到任何内容.

我发现了一些“修复”:

>不要在我的“DB”类中扩展mysqli类;这使得它不起作用,但似乎表明扩展mysqli会导致问题.

>全局或在我的ErrorHandler.php类文件的顶部自动加载我自己的“DB”类.

>在ErrorHandler类中获取实例之前,使用require_once显式加载“DB”类.

我仍然可以在ErrorHandler中自动加载其他类,但是当我实例化“DB”时,PHP似乎崩溃了.

从我看到的,唯一合理的解释似乎是mysqli中的某些内容与在ErrorHandler类中首次实例化的范围有关,因为所有有效的修复似乎都共享范围方面,但这似乎没有任何意义上的.

有谁知道这里发生了什么?

类加载器…

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

D B…

class DB extends mysqli {

private static $_instances = array();

public static function get(Config $config) {

$hash = md5(serialize($config));

if (!array_key_exists($hash, self::$_instances)) {

self::$_instances[$hash] = new self($config);

}

return self::$_instances[$hash];

}

private $_prefix = '';

private $_die = false;

public function dieOnError($die) { $this->_die = $die; }

private function __construct(Config $config) {

parent::__construct(

$config->host

, $config->username

, $config->password

, $config->database

);

if ($this->connect_error) {

_report_error($this->connect_errno, $this->connect_error);

}

$this->_prefix = $config->prefix;

}

}

Config是一个拥有一些公共属性的单身人士.

的ErrorHandler

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("
\n%s: %s in %s on line %d
\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;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值