|
本帖最后由 imwebmaster.net 于 2012-5-11 19:05 编辑
学习CI ,开始读CI的代码,发现PHP基础是那么的重要。一个函数就把我搞晕了。
在CodeIgniter.php 中 我们设置自定义的_exception_handler函数作为异常处理程序
该函数位于Common.php中。
PHP复制代码
function _exception_handler ($severity, $message, $filepath, $line)
{
if ($severity == E_STRICT)
{
return;
}
$_error =& load_class ('Exceptions', 'core');
if (($severity & error_reporting()) == $severity)
{
$_error->show_php_error($severity, $message, $filepath, $line);
}
//略
}
复制代码
其中 $severity & error_reporting() =?呢? 分析一下
1. $serverity 实为 error_handler 的 errorno
2. & 为位与操作符
3. error_reporting([int level]) 可以用来设置错误报告级别,省略参数 则返回当前错误报告级别
当异常发生时, error_handler 被传递到 _exception_handler 函数 ,$severity = errno, 错误报告级别,为整数.
如果ENVIROMENT ='development'(默认) , 那么错误报告级别被设置为 E_ALL .也是整数
那么,$severity & error_reporting() 这个表达式返回什么值,关键在于理解 & 位与操作符 第一个数值的位 | 第二个数值的位 | 结果 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
接下来 先看一下各错误报告级别 常量和值
常量 | 值 | 二进制 | E_ERROR | 1 | 0000 0000 0000 0001 | E_WARNING | 2 | 0000 0000 0000 0010 | E_PARSE | 4 | 0000 0000 0000 0100 | E_NOTICE | 8 | 0000 0000 0000 1000 | E_CORE_ERROR | 16 | 0000 0000 0001 0000 | E_CORE_WARNING | 32 | 0000 0000 0010 0000 | E_COMPILE_ERROR | 64 | 0000 0000 0100 0000 | E_COMPILE_WARNING | 128 | 0000 0000 1000 0000 | E_USER_ERROR | 256 | 0000 0001 0000 0000 | E_USER_WARNING | 512 | 0000 0010 0000 0000 | E_USER_NOTICE | 1024 | 0000 0100 0000 0000 | E_ALL | 2047 | 0000 0111 1111 1111 | E_STRICT | 2048 | 0000 1000 0000 0000 | | | | | | | (备:表中二进制是16位 的,在实际的情况下可能以32位的来计算)
好吧,首先假设 ($severity & error_reporting()) == $severity 返回TRUE 。
$severity | 0000 0*** **** **** | & (E_ALL) | 0000 0111 1111 1111 | 结果 | 0000 0--- ---- ----- |
按照位与的规则,尝试将* 替换为0或1 ,你是不是发现无论如何 ,结果都是等于$severity
除非$severity 的最高位超出了我用红色标记的最高位,错误级别中,只有E_STRICT菜能做到这一点
$severity | 0000 1000 0000 000 | & (E_ALL) | 0000 0111 1111 1111 | 结果 | 0000 0000 0000 0000 |
$severity = E_STRICT 的情况已经做了处理。
PHP复制代码
if ($severity == E_STRICT)
{
return;
}
复制代码
由此得出一个结论 : 异常错误级别低于 E_ALL时,用$_error->show_php_error来报告错误?。
这条结论建立在初始化设置的错误级别为E_ALL 的基础上,假如不是,这还成立嘛?
$severity | 0000 0********** | & error_reporting() | 0000 0********** | 结果 | ------ |
回头再看一下 位与操作的那个表。当errot_reporting()不等于E_ALL时候 ,也就是说errot_reporting()不可能每一位都为1 。
这就导致了$severity 中的1对到errot_reporting()的0时 ,该位上就变成了0. 因此 $severity & error_reporting() 的返回值
永远都是 <= $severity 的。那啥时候等于 啥时候小于呢(我快崩溃了)。
看一下错误报告级别 常量和值这张表,不难发现一件事请,错误常量二进制表示中的每一位代表了一种错误级别.如果这位上为1 说明了这个错误级别开启,0则关闭。
---------------
平常,我们使用 位运算符 ! ^ ~ 来设置我们的错误报告级别,实际上就是来操作每个位吧?
比如 error_reporting = E_ERROR | E_PARSE | E_CORE_ERROR
| 位或操作符 对应的位一个为1 结果为1。 真假真嘛
0000 0000 0000 0001
0000 0000 0000 0100
0000 0000 0001 0000
结果 = 0000 0000 0001 0101
-----------
因此 当$severity 的level 不在 error_reporting() 的levels 中 。那么相应位上的1 碰到的永远是0 ,这种情况下 ,$severity & error_reporting() 的返回值 实际上为 0 。
而当$severity 的level 在 error_reporting() 的levels 中。那么相应位上的1碰到的也是1 ,这种情况下$severity & error_reporting() 的返回值 实际上为 $severity 。
结论:异常的level 在 初始设置的 levels 中 异常将 被 $_error->show_php_error。
另外 我查了一下目前PHP错误报告级别 ,发现在 PHP.5.2.X 之后的版本中E_ALL的值已经不等于2047了
32767 in PHP 5.4.x, 30719 in PHP 5.3.x, 6143 in PHP 5.2.x,
但不管如何 新的值各位上依然是1 ,如 32767 =》111111111111111 。遗憾啊,小弟不是计算机专业毕业的,不知道这样的数值 有没有专有的名词啊。我想应该有的吧,谁知道麻烦告诉我一下咯。
另外啊,也不知以上论述有没有问题,有的话,希望大家能积极的指导我一下。
|
评分
-
查看全部评分
|