PHP内核中的异常基类
在<<思考PHP语言三:异常处理>>中有说到异常的定义:异常处理是指在语言中能够使程序按照一种标准的方法对于某些运行时错误和其他程序所检测到的异常事件做出反应。异常发生的时间是不可以确定的,如果一种语言不包括异常处理机制,这就会给语言带来额外的复杂性。对于异常的处理有三种方案,而PHP5使用的是将一个异常处理独立出来,作为专门的子程序或类存在。
Exception是PHP中所有异常的基类,自从PHP5.1.0开始引入,自此,我们可以以面向对象的方式处理错误。 Exception类的声明如下:
Exception { /* 属性 */ protected string $message ; protected int $code ; protected string $file ; protected int $line ; /* 方法 */ public __construct ([ string $message = "" [, int $code = 0 [, Exception $previous = NULL ]]] ) final public string getMessage ( void ) final public Exception getPrevious ( void ) final public int getCode ( void ) final public string getFile ( void ) final public int getLine ( void ) final public array getTrace ( void ) final public string getTraceAsString ( void ) public string __toString ( void ) final private void __clone ( void ) } |
其中message表示异常消息内容,code表示异常代码,file表示抛出异常的文件名,line表示抛出异常在该文件中的行号。下面从 PHP内核的角度说明这些属性及对应的方法。
message表示异常的消息内容,其对应getMessage方法。message是自定义的异常消息,默认为空字符串。对于PHP内核来说,创建Exception对象时,有无message参数会影响 getMessage方法的返回值,以及显示异常时是否有with message %s等字样。message成员变量的作用是为了让用户更好的定义说明异常类。
code表示异常代码,其对应getCode方法。和meesage成员变量一样,code也是用户自定义的内容,默认为0。
file表示抛出异常的文件名,其对应getFile方法,返回值为执行文件的文件名,在PHP内核中存储此文件名的字段为 EG(active_op_array)->filename 此字段的值在生成一个opcode列表时,PHP的内核会将此前正在编译文件的文件名赋值给opcode的filename属性,如生成一个函数的op_array,在初始化op_array时,会执行上面所说的赋值操作,这里的赋值是通过编译的全局变量来传递的。当代码执行时,EG(active_op_array)表示正在执行的opcode列表。
line表示抛出异常在该文件中的行号,其对应getLine方法,返回整数,即EG(opline_ptr)->lineno。对于每条PHP脚本生成的opcode,在编译时都会执行一次初始化操作,在这次初始化操作中,PHP内核会将当前正在编译的行号赋值给opcode的lineno属性。 EG(opline_ptr)是PHP内核执行的当前opcode,抛出异常时对应的行号即为此对象的lineno属性。
除了上面四个属性,异常类还包括一个非常重要的内容:异常的追踪信息。在异常类中,通过getTrace方法可以获取这些信息。此方法的作用相当于PHP的内置函数debug_backtrace。在代码实现层面他们最终都是调用zend_fetch_debug_backtrace函数。在此函数中通过回溯PHP的调用栈,返回代码追踪信息。与getTrace方法对应还有一个返回被串化值的方法getTraceAsString,以字符串替代数组返回异常追踪信息。
在构造函数中,从PHP5.3.0增加$previous参数,表示异常链中的前一个异常。在catch块中可以抛出一个新的异常,并引用原始的异常,为调试提供更多的信息。
您可能姓潘吧,姑且暂时冒昧称呼你为潘先生
您好潘先生:
今天不知道为什么思路会这么混乱,回来想一下这个题,到家一下就解出来了,一共才几个函数而已,感觉自己问题出在动手太少了,而且基础不牢固,像strpps这么基本的都给忘掉了,我也是太混球了点。您说的也非常正确,基础一定要牢固,才能考虑做其他的事情,像我php基础和mysql都是非常薄弱的,自己要加强练习了,希望以后能机会与你合作,抱歉今天打扰浪费你的时间了。你还玩twitter啊。
/*
* 获取上月的今天,如果没有则输出上月最后一天,需要传3个参数$day,$month,$year
*/
function getLastday($day,$month,$year=2012){
if($month ==1){ //判断月份是否为一月,如果是则为去年,因为1月和12月都有31号所以不用输出12月最后一天
$year = $year -1;
$month = 12;
return date(“Y-m-d”, mktime(0, 0, 0, $month, $day, $year));
}
if(checkdate($month-1, $day, $year)){
return date(“Y-m-d”, mktime(0, 0, 0, $month-1, $day, $year));
}else{
$month = $month-1;
$lastmonth = “$year/$month/1″;
return date(‘Y-m-t’,strtotime(“$lastmonth”));
}
}
刚刚看了你的博客的文章,真是很佩服你,你都了解PHP内核工作原理了,加油希望有一天能超过你。
博主,你好,看了你的博客,很多东西写的真心不错,对我这种菜鸟来说还有很多学习的地方,我现在还是一个大三的学生,在聚美实习,现在在学习扩展和读PHP的代码,希望多多向您学习
php内核。。。老大,收徒不