前段时间在网上看到一篇高级PHP程序设计的话题,其中提到对代码执行时间的处理,以及对异常的处理。 然后自己写了对这部分代码。其中很大一部分来自项目中的学习,分享一下,也算是对自己学习的总结。
(一). 对代码执行时间的处理。
这在PHP里应该是很简单的。只要在代码执行初获得初始时间,然后再代码执行的最后一行代码获得结束时间,然后求得差值就可以了。
function get_microtime() {
list ( $usec , $sec ) = explode ( ' ' , microtime ());
return ( float ) $sec + ( float ) $sec ;
}
?>
(二) 对异常的处理。
现在对基于PHP的开发,两种思想是不可少的,一种是基于OO的思想,另外就是对layout和logic的分离。这里对异常处理的介绍,是基于OO的设计。对于在PHP的开发中采用的模板引擎,可以参考smarty.php.net.
对逻辑的处理,可以如下设计:
/* *
* This is the logic base class.
* Author: Wyatt Fang
* Created time: 01/28/2006
*/
abstract class PageLayout {
// common members varibles put here, such as db handler and other parts.
public function __construct() {
// common initialize
}
// other common functions
//....
abstract public function doGet();
abstract public function doPost();
}
?>
这是页面逻辑的基类。以后每个页面的逻辑代码都继承此类。例如,对于主页,可以写成这样:
// This is the index.php file.
class MainPage extends PageLayout {
$mysql_runner ;
// other member variables.
public function doGet() {
// if the request method is "GET", all logics put here
}
public function doPost() {
// if the request method is "POST", all logics put here
}
// ...other functions used in the doGet or doPost function.
}
?>
在上面的代码中提到了一个方法run(),这是一个驱动函数。这个方法定义在一个lib-functions.php的文件里面,而我们的异常处理函数就定义在这个文件里面,先看一下run()方法的代码,
function run( $page ) {
$current_page = new $page ;
// some header information put here
try {
switch ( $_SERVER [ ' REQUEST_METHOD ' ]) {
case " POST " :
$current_page -> doPost();
break ;
case " GET " :
$current_page -> doGet();
break ;
}
}
catch (PHPException $e ) { // if there are exception throwed out
trace_exception( $e ); // trace the exception
die ();
}
catch (MySQLException $e ) {
trace_exception( $e );
die ();
}
catch ( Exception $e ) {
trace_exception( $e );
die ();
}
}
?>
我们把run方法放在lib-functions.php里面,同时在include.php文件里面添加:
include_once ' lib-functions.php ' ;
?>
同时我们看到在类MainPage里面,我们已经引进了run函数,这样整个系统就驱动了起来。现在做了这么多辅助的工作,可以正式进入异常处理的话题了。
因为在run方法中包装了对各个页面logic的调用,所有在我们自定义的类中定义的过程(例如MainPage)出现的异常,我们可以在run方法的try...catch里面捕捉到,然后对它进行调试或执行输出。
我们将异常处理的函数添加到lib-functions.php文件中:
/* *
* Sets the exception handler
*/
function catch_error_as_exception() {
set_error_handler ( " throw_error_as_exception " , E_ALL );
}
/* *
* when exception happens, throw it as PHPException
*/
function throw_error_as_exception( $code , $message , $file , $line ) {
throw new PHPException( $message , $code , $file , $line );
}
/* *
* Print the exception out used for debug.
*/
function print_vars( $e ) {
echo ' <pre style="color:#0000FF;text-align:left;margin:0px;padding:0px;"> ' ;
print_r ( $e );
echo ' </pre> ' ;
}
function trace_exception( $e ) {
if ( defined ( ' DEBUGER ' )) {
print_vasr( get_class ( $e ) . ' Caught: ' );
print_vars( ' ( ' . $e -> getLine() . ' ) ' . $e -> getFile() . " : " . $e -> getMessage());
print_vars( $e -> getTrace());
}
else {
print_var( ' System internal error... ' );
}
}
function rum ....
?>
在run函数里面,当我们捕捉到异常时,会将异常交给trace_exception()进行处理,trace_exception会将异常的详细信息打印出来,供调试之用。在程序最终发布之后,可以去掉条是信息。
然后我们还需要做一些事情,就是调用方法catch_error_as_exception(), 把系统的异常转化为我们自定义的异常类来处理。我们在include.php文件里面添加对catch_error_as_exception的调用,因为我们设计的每个类,都会在文件头添加对include.php文件的引用操作(include 'include.php'):
catch_error_as_exception();
// ...other include files
?>