PHP自定义异常处理

来源:互联网 发布:java抽象类构成 编辑:程序博客网 时间:2024/05/17 04:42

        前段时间在网上看到一篇高级PHP程序设计的话题,其中提到对代码执行时间的处理,以及对异常的处理。 然后自己写了对这部分代码。其中很大一部分来自项目中的学习,分享一下,也算是对自己学习的总结。

        (一). 对代码执行时间的处理。
         这在PHP里应该是很简单的。只要在代码执行初获得初始时间,然后再代码执行的最后一行代码获得结束时间,然后求得差值就可以了。

<?php
function get_microtime() {
    
list($usec, $sec= explode('  ', microtime());
  
    
return (float)$sec + (float)$sec;
}
?>

        (二) 对异常的处理。
        现在对基于PHP的开发,两种思想是不可少的,一种是基于OO的思想,另外就是对layout和logic的分离。这里对异常处理的介绍,是基于OO的设计。对于在PHP的开发中采用的模板引擎,可以参考smarty.php.net.
        对逻辑的处理,可以如下设计:

<?php
/**
 * 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();
}
?>

        这是页面逻辑的基类。以后每个页面的逻辑代码都继承此类。例如,对于主页,可以写成这样:

<?php
//This is the index.php file.
    include 'include.php'; //all the files included in this single 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('MainPage');//this function is to show the main page.
?>

        在上面的代码中提到了一个方法run(),这是一个驱动函数。这个方法定义在一个lib-functions.php的文件里面,而我们的异常处理函数就定义在这个文件里面,先看一下run()方法的代码,

<?php
    
    
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文件里面添加:

<?php
include_once 
'lib-functions.php';
    //...other includes files put here
?>

       同时我们看到在类MainPage里面,我们已经引进了run函数,这样整个系统就驱动了起来。现在做了这么多辅助的工作,可以正式进入异常处理的话题了。
        因为在run方法中包装了对各个页面logic的调用,所有在我们自定义的类中定义的过程(例如MainPage)出现的异常,我们可以在run方法的try...catch里面捕捉到,然后对它进行调试或执行输出。
        我们将异常处理的函数添加到lib-functions.php文件中:

<?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() . ":&nbsp;&nbsp;" . $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'):

<?php
catch_error_as_exception();
//...other include files
?>
        这样,我们就用面向对象的方法设计我们的功能类,并把logic和layout进行了分离,当开发过程中遇到错误时候,还能用我们定义的错误处理函数打印出所有的错误信息,而不会再看到系统默认的难堪的错误信息了。
原创粉丝点击