PHP 开发经典教程 (Part 12):程序缺陷排除(3)_PHP应用_黑客防线网安服务器维护基地--Powered by WWW.RONGSEN.COM.CN

PHP 开发经典教程 (Part 12):程序缺陷排除(3)

作者:黑客防线网安PHP维护基地 来源:黑客防线网安PHP维护基地 浏览次数:0

本篇关键词:程序缺陷排除教程
黑客防线网安网讯:   set_error_handler()函数告诉脚本所有的错误都将被路由到我的用户自定义的oops()函数。该函数被建立以接受五个参数:错误类型、消息、文件名称、行号以及包含关于错误发生的上下文(包括服...

   set_error_handler()函数告诉脚本所有的错误都将被路由到我的用户自定义的oops()函数该函数被建立以接受五个参数:错误类型、消息、文件名称、行号以及包含关于错误发生的上下文(包括服务器和平台以及脚本信息)的许多信息的数组上下文数组的最终元素包含有错变量的当前值。然后这些参数被用于创建一个比PHP标准的单行错误消息更友好且信息更丰富的错误提示页面。

你可以使用此自定义的错误处理器在错误类型的基础上来改变用户所看到的错误消息。请看下一个例子该例子演示了该技术的使用:


  

undefined
undefined
   <?
    php

    //
     define a custom error handler
   

    set_error_handler(
    '
    oops
    '
    );

    //
     initialize $string variable
   

    $
    string
    
    =
    
    '
    a string
    '
    ;

    //
     this will generate a warning
   

    explode($
    string
    );

    //
     custom error handler
   

    function oops($type, $msg, $file, $line, $context) {

    switch
     ($type) {

    //
     notices
   

   case
     E_NOTICE:

    //
     do nothing
   

   break
    ;

    //
     warnings
   

   case
     E_WARNING:

    //
     report error
   

    print
    "
    Non-fatal error on line $line of $file: $msg <br />
    "
    ;

    break
    ;

    //
     other
   

   default
    :
print
    "
    Error of type $type on line $line of $file: $msg <br />
    "
    ;

    break
    ;
}
}

    ?>
    

请注意某些错误类型不能使用该方法处理。举例而言,一条致命的E_ERROR将阻止PHP脚本的继续执行,因此,它永远无法达到用户自定义的错误处理机制。访问http://www.php.net/set-error-handler以获得更多的关于这点的信息。
  
第二部分-

扣动扳机

到目前为止,我们一直在讨论处理由PHP自身所产生的错误,但为什么要停留在那里呢?PHP也允许你使用其内建的错误处理系统来生成你自己自定义的错误。

这是通过一个名为trigger_error()的函数来完成的,该函数允许你生成为用户所保留的三种错误类型中的任意一个:E_USER_NOTICE、E_USER_WARNING和E_USER_ERROR。当这些错误被触发时,PHP内建的处理器将会自动唤醒以处理这些错误。
   

undefined
undefined
    <?
     php

     //
      function to test a number

     //
      generates E_USER_WARNING if number is a float

     //
      generates E_USER_ERROR is number is negative
    

     function testNumber($num) {

     //
      float

     //
      trigger a warning
    

    if
      (is_float($num)) {
trigger_error(
     "
     Number $num is not an integer
     "
     , E_USER_WARNING);
}

     //
      negative

     //
      trigger a fatal error
    

     if
      ($num
     <
     
     0
     ) {
trigger_error(
     "
     Number $num is negative
     "
     , E_USER_ERROR);
}
}

     //
      test the function with different values
    

     testNumber(
     100
     );
testNumber(
     5.6
     );
testNumber(
     -
     8
     );

     ?>
     
如果你打算用一个自定义的错误处理器来处理你自定义的错误……,嗯,你只是很难满足的,不是吗?请看下这个例子,该例子重新编写了之前的脚本以使用用户自定义的错误处理器:
   

undefined
undefined
    <?
     php

     //
      function to test a number

     //
      generates E_USER_WARNING if number is a float

     //
      generates E_USER_ERROR is number is negative
    

     function testNumber($num) {

     //
      float

     //
      trigger a warning
    

    if
      (is_float($num)) {
trigger_error(
     "
     Number $num is not an integer
     "
     , E_USER_WARNING);
}

     //
      negative

     //
      trigger a fatal error
    

     if
      ($num
     <
     
     0
     ) {
trigger_error(
     "
     Number $num is negative
     "
     , E_USER_ERROR);
}
}

     //
      custom error handler
    

     function myErrorHandler($type, $msg, $file, $line, $context) {

     switch
      ($type) {

     //
      warnings
    

    case
      E_USER_WARNING:

     //
      report error
    

     print
     "
     Non-fatal error on line $line of $file: $msg <br />
     "
     ;

     break
     ;

     //
      fatals
    

    case
      E_USER_ERROR:

     //
      report error and die()
    

     die(
     "
     Fatal error on line $line of $file: $msg <br />
     "
     );

     break
     ;

     //
      notices
    

    default
     :

     //
      do nothing
    

    break
     ;
}
}

     //
      set the name of the custom handler
    

     set_error_handler(
     '
     myErrorHandler
     '
     );

     //
      test the function with different values
    

     testNumber(
     100
     );
testNumber(
     5.6
     );
testNumber(
     -
     8
     );

     ?>
     
 请注意,如果用户产生致命错误发生的话,那么调用die()函数是自定义的处理器的责任(PHP不会自动做这个的)。
你也可以使用同样的方法来处理异常。请向下滚动鼠标,让我向你展示如何去做。

捕获

如果你正在使用PHP 5,那么除了目前为止所讨论的关于新的异常模型技术(异常是另外一种错误)之外你也有其他的选择。异常是PHP中新出现的技术(虽然它们已经在诸如Java和Python语言中多年了)而且它们正在引起人们大量的激动。

在基于异常的方法中,程序代码被try()块结构包围起来然后该代码所产生的异常被catch()块结构“捕获”和解决。多个catch()块是可能的,其中每一个处理不同的错误类型;这就允许开发人员捕获不同类型的错误而且执行适当的异常处理。

下面是一个典型的try-catch()块看上去的样子:
   

undefined
undefined
    try
      {
execute
     this
      block
}

     catch
      (exception type
     1
     ) {
execute
     this
      block to resolve exception type
     1
    
}

     catch
      (exception type
     2
     ) {
execute
     this
      block to resolve exception type
     2
    
}
诸如此类……

当PHP遇到被包含在try-catch()块内部的代码时,它首先试图执行try()块内部的代码。如果该代码被处理时无异常产生,那么控制就转移到try-catch()块之后的代码行。然而,如果在运行try()块内部的代码时产生了异常,那么PHP在发生异常的地方停止该try()块的执行然后检查每个catch()块以查看是否有一个该异常的处理器。如果找到一个处理器,那么在适当的catch()块内部的代码得到执行;如果没有找到,那么就产生一个致命的错误。使用异常以一种良好的方式来处理该致命错误甚至也是可能的;请访问http://www.php.net/set-exception-handler以获得更多的关于这方面的内容:
异常本身通过PHP的throw语句来产生。Throw语句需要被传递一个描述性消息和一个可选的错误代码。当异常被产生时,该描述和代码将会对异常处理器变得可用。

想要看看这是如何工作的吗?下面是一个例子:
   

undefined
undefined
    <?
     php

     //
      PHP 5
    

    
error_reporting(
    0
     );

     //
      try this code
    

    try
      {
$file
     =
     
     '
     somefile.txt
     '
     ;

     //
      open file
    

     if
      (
     !
     $fh
     =
      fopen($file,
     '
     r
     '
     )) {

     throw
     
     new
      Exception(
     '
     Could not open file!
     '
     );
}

     //
      read file contents
    

     if
      (
     !
     $data
     =
      fread($fh, filesize($file))) {

     throw
     
     new
      Exception(
     '
     Could not read file!
     '
     );
}

     //
      close file
    

     fclose($fh);

     //
      print file contents
    

     echo $data;
}

     //
      catch errors if any
    

    catch
      (Exception $e) {
print
     '
     Something bad just happened...
     '
     ;
}

     ?>
     
如果文件不存在或不可读,那么throw语句将会产生一个异常(基本上,PHP内建异常对象的一个实例)然后为其传递一个描述错误的消息。当这样的异常被产生时,程序控制转到第一个catch()块。如果该catch()块可以处理该异常类型,那么该catch()块内部的代码得到执行。如果第一个catch()块不能处理所产生的异常,那么程序控制就转移到下一个catch()块中。

不要在该点上对“异常类型”过多担心(所有的都会被简单介绍)。目前,所有你需要知道的就是上面的catch()块将会捕获所有的异常而无论其类型。

现在,之前的代码清单中有一个问题。虽然catch()块将会捕获异常然后打印一条消息,但是它不能显示throw语句所发送的异常的描述性消息。为了访问该消息和一些其他有趣的信息片段,有必要使用一些Exception对象内建的方法。请看之前脚本的修订版,其对此做了解释说明:
   

undefined
undefined
    <?
     php

     //
      PHP 5
    

    
error_reporting(
    0
     );

     //
      try this code
    

    try
      {
$file
     =
     
     '
     somefile.txt
     '
     ;

     //
      open file
    

     if
      (
     !
     $fh
     =
      fopen($file,
     '
     r
     '
     )) {

     throw
     
     new
      Exception(
     '
     Could not open file!
     '
     ,
     12
     );
}

     //
      read file contents
    

     if
      (
     !
     $data
     =
      fread($fh, filesize($file))) {

     throw
     
     new
      Exception(
     '
     Could not read file!
     '
     ,
     9
     );
}

     //
      close file
    

     fclose($fh);

     //
      print file contents
    

     echo $data;
}

     //
      catch errors if any
    

    catch
      (Exception $e) {
print
     '
     <h2>Exception</h2>
     '
     ;
print
     '
     Error message:
     '
      . $e
     ->
     getMessage() .
     '
     <br />
     '
     ;
print
     '
     Error code:
     '
      . $e
     ->
     getCode() .
     '
     <br />
     '
     ;
print
     '
     File and line:
     '
      . $e
     ->
     getFile() .
     '
     (
     '
      . $e
     ->
     getLine() .
     '
     )<br />
     '
     ;
print
     '
     Trace:
     '
      . $e
     ->
     getTraceAsString() .
     '
     <br />
     '
     ;
}

     ?>
     
当你运行该脚本时,你会看到异常处理器所产生的消息包含如下内容:
? throw语句发送的描述性数据,
? 错误代码(也是被throw语句发送的)
? 异常发生地的文件名称和行号,以及
? 以类层次结构指示异常过程的堆栈跟踪信息,如果有的话。
该数据是通过在catch()块内分别调用Exception对象的getMessage()、getCode()、getFile()、getLine()和getTraceAsString()方法而产生的。

添加一些类

你可以通过子类化的Exception对象然后使用多个catch()块以不同的方法来处理不同的异常。下面的例子是对这点的一个简单解释:
   

undefined
undefined
    <?
     php

     //
      PHP 5

     //
      sub-class the Exception class
    

    class
      NegativeNumException extends Exception {}

     class
      OutOfRangeException extends Exception {}

     class
      FloatException extends Exception {}

     //
      function to test a number
    

     function testNumber($num) {

     //
      float

     //
      trigger an exception
    

    if
      (is_float($num)) {

     throw
     
     new
      FloatException($num);
}

     //
      negative

     //
      trigger an exception
    

     if
      ($num
     <
     
     0
     ) {

     throw
     
     new
      NegativeNumException($num);
}

     //
      out of range

     //
      trigger an exception
    

     if
      ($num
     >
     
     1000
     
     ||
      $num
     <
     
     100
     ) {

     throw
     
     new
      OutOfRangeException($num);
}
}

     //
      try this code
    

    try
      {
testNumber(
     -
     19
     );
}

     //
      catch errors, if any
    

    catch
      (NegativeNumException $e) {
print
     '
     A negative number was provided (
     '
     .$e
     ->
     getMessage().
     '
     ). Please provide a positive integer between 100 and 1000.<br />
     '
     ;
}

     catch
      (OutOfRangeException $e) {
print
     '
     The number provided is out of range (
     '
     .$e
     ->
     getMessage().
     '
     ). Please provide a positive integer between 100 and 1000.<br />
     '
     ;
}

     catch
      (FloatException $e) {
print
     '
     The number provided is not an integer (
     '
     .$e
     ->
     getMessage().
     '
     ). Please provide a positive integer between 100 and 1000.<br />
     '
     ;
}

     catch
      (Exception $e) {
print
     '
     Error message:
     '
      . $e
     ->
     getMessage() .
     '
     <br />
     '
     ;
print
     '
     Error code:
     '
      . $e
     ->
     getCode() .
     '
     <br />
     '
     ;
print
     '
     File and line:
     '
      . $e
     ->
     getFile() .
     '
     (
     '
      . $e
     ->
     getLine() .
     '
     )<br />
     '
     ;
print
     '
     Trace:
     '
      . $e
     ->
     getTraceAsString() .
     '
     <br />
     '
     ;
}

     ?>
     
在该例子中,我已经从基本的对象创建了三种新的Exception子类,每个可能的错误一个子类。接着,我为每个异常类型建立了catch()块,然后编写了特定于每种类型的异常处理代码。根据发生哪类异常(你可以向testNumber()函数发送不同的值来产生不同的异常),调用适当的catch()块然后打印不同的错误消息。

请注意,因为PHP会一直使用与异常类型匹配的第一个catch()块,而且因为Exception类匹配所有的异常,所以catch()块必须按照最精确的catch()块优先的顺序进行排列。这个在上述例子中已经实现,上述例子中,catch()块出现在列表的最后。

    黑客防线网安服务器维护方案本篇连接:http://www.rongsen.com.cn/show-13900-1.html
网站维护教程更新时间:2012-03-30 05:03:22  【打印此页】  【关闭
我要申请本站N点 | 黑客防线官网 |  
专业服务器维护及网站维护手工安全搭建环境,网站安全加固服务。黑客防线网安服务器维护基地招商进行中!QQ:29769479

footer  footer  footer  footer