zoukankan      html  css  js  c++  java
  • 函数用户PHP自学之路错误及异常处理机制、错误日志

    最近应用开发的过程中出现了一个小问题,顺便记录一下原因和方法--函数用户

        

    PHP错误机制

        

     

        

        

        

    在 PHP 中,默许的错误处置很简略。一条消息会被发送到浏览器,这条消息带有文件名、行号以及一条描述错误的消息。在创立脚本和 web 应用程序时,错误处置是一个重要的部份。如果您的代码缺少错误检测编码,那么程序看上去很不专业,也为安全风险敞开了大门。

        

     PHP 中一些最为重要的错误检测方法。

        

    • 简略的 "die()" 语句

          

    if(!file_exists("../func.php")){
    		die("文件不存在<br/>");
    	} else {
    		$fp=fopen("../func.php","r");
    		echo "文件打开胜利<br/>";
    		//..关闭
    		fclose($fp);
    	}    
    • 更简洁的方法

        

        

    file_exists("func.php") or die("文件不存在<br/>");

        

      这句相当于把上面的if...else合并到一起了!

        

    • 创立自定义错误检测机制

        

         看下面的代码,假设文件是不存的运行的时候会报错如下:

    <?php
    $file=fopen("welcome.txt","r");
    ?>

        

    错误信息如下(PHP默许的错误处置机制):

    Warning: fopen(welcome.txt) [function.fopen]: failed to open stream: 
    No such file or directory in C:\webfolder\test.php on line 2

        
     

        

    创立一个自定义的错误处置器非常简略。我们很简略地创立了一个专用函数,可以在 PHP 中发生错误时调用该函数。该函数必须有能力处置最少两个参数 (error level 和 error message),但是可以接受最多五个参数(可选的:file, line-number 以及 error context):

        

        系统自带的错误函数:

    error_function(error_level,error_message,error_file,error_line,error_context)

        
    参数分析:

        

    参数描述
    error_level

    必需。为用户定义的错误规定错误报告级别。必须是一个值数。

    拜见下面的表格:错误报告级别。

    error_message 必需。为用户定义的错误规定错误消息。
    error_file 可选。规定错误在其中发生的文件名。
    error_line 可选。规定错误发生的行号。
    error_context 可选。规定一个数组,包含了当错误发生时在用的每个变量以及它们的值。

        

     

        

    错误报告级别

        

    这些错误报告级别是错误处置程序旨在处置的错误的不同的类型:

    常量描述
    2 E_WARNING 非致命的 run-time 错误。不暂停脚本执行。
    8 E_NOTICE

    Run-time 通知。

    脚本发明可能有错误发生,但也可能在脚本畸形运行时发生。

    256 E_USER_ERROR 致命的用户生成的错误。这类似于程序员应用 PHP 函数 trigger_error() 设置的 E_ERROR。
    512 E_USER_WARNING 非致命的用户生成的警告。这类似于程序员应用 PHP 函数 trigger_error() 设置的 E_WARNING。
    1024 E_USER_NOTICE 用户生成的通知。这类似于程序员应用 PHP 函数 trigger_error() 设置的 E_NOTICE。
    4096 E_RECOVERABLE_ERROR 可捕获的致命错误。类似 E_ERROR,但可被用户定义的处置程序捕获。(拜见 set_error_handler())
    8191 E_ALL

    全部错误和警告,除级别 E_STRICT 以外。

    (在 PHP 6.0,E_STRICT 是 E_ALL 的一部份)

        

    错误报告级别

        

    这些错误报告级别是错误处置程序旨在处置的错误的不同的类型:

    常量描述
    2 E_WARNING 非致命的 run-time 错误。不暂停脚本执行。
    8 E_NOTICE

    Run-time 通知。

    脚本发明可能有错误发生,但也可能在脚本畸形运行时发生。

    256 E_USER_ERROR 致命的用户生成的错误。这类似于程序员应用 PHP 函数 trigger_error() 设置的 E_ERROR。
    512 E_USER_WARNING 非致命的用户生成的警告。这类似于程序员应用 PHP 函数 trigger_error() 设置的 E_WARNING。
    1024 E_USER_NOTICE 用户生成的通知。这类似于程序员应用 PHP 函数 trigger_error() 设置的 E_NOTICE。
    4096 E_RECOVERABLE_ERROR 可捕获的致命错误。类似 E_ERROR,但可被用户定义的处置程序捕获。(拜见 set_error_handler())
    8191 E_ALL

    全部错误和警告,除级别 E_STRICT 以外。

    (在 PHP 6.0,E_STRICT 是 E_ALL 的一部份)

        

    下面是我们自己实现的错误处置函数:

    <?php
    //自定义自己的错误处置函数
    	function myerror($errno,$errstr){
    		echo "<font size='5' color='red'>$errno</font><br/>";
    		echo "错误信息:".$errstr;
    	}
    	//这里我们还须要改写set_error_handler
    	/*PHP 的默许错误处置程序是内建的错误处置程序。我们盘算把上面的函数改革为脚本运行期间的默许错误处置程序。set_error_handler() 仅须要一个参数,可以添加第二个参数来规定错误级别。
         */
    
    	set_error_handler("myerror",);
    
    	echo($test);
    	/*输出下面的内容:
    	 8
         错误信息:Undefined variable: test
    	 */
    ?>

        


    错误触发器:

        

       错误触发器和错误处置器区别:触发器往往处置逻辑上的错误,处置器处置系统上的错误:

        

     看下面的需求:当输入春秋大于120时,会触发错误!

    $age = 200;
    	 if($age>120){
    		  trigger_error("the age is logger!",E_USER_WARNING);
    	      exit();
    	 }

        

    运行上面的代码会出现下面的错误:

        

    Warning: the age is logger! in /var/myphp/exec/File.php on line 3

        

    看处置器一样,上面的警告信息是系统打印出来的。那么我们将处置器和错误触发器共同应用,看下面的代码:

        

    	<?php //自定义自己的错误处置函数
    	function myerror($errno,$errstr){
    		echo "<font size='5' color='red'>$errno</font><br/>";
    		echo "错误信息:".$errstr;
    	}
    	//指定错误的处置函数,
         set_error_handler("myerror",E_USER_WARNING);
    	 $age = 200;
    	 if($age>120){
    		 //E_USER_WARNING 这里必须和制订错误处置函数对应,否则还是会调用系统错误处置函数
    		  trigger_error("the age is logger!",E_USER_WARNING);
    	      exit();
    	 }
    	 /*512
         错误信息:the age is logger!
    	 */
    ?>


    可能的错误类型:

        

    • E_USER_ERROR - 致命的用户生成的 run-time 错误。错误没法恢复。脚本执行被中断。
    • E_USER_WARNING - 非致命的用户生成的 run-time 警告。脚本执行不被中断。
    • E_USER_NOTICE - 默许。用户生成的 run-time 通知。脚本发明了可能的错误,也有可能在脚本运行畸形时发生。

        

     错误日志:

        

    http://blog.csdn.net/heiyeshuwu/article/details/577838 这个博客有介绍,可以看看!

        

     默许地,根据在PHP.ini中的error_log配置,PHP想服务器的错误记录系统或者文件发送错误日志,通过应用error_log()函数,您可以向指定的文件或远程目的地发送错误记录

        

     bool error_log ( string message [, int message_type [, string destination [, string extra_headers]]] )

        


    <?php
    
    
         //设置时区
    	 date_default_timezone_set("Asia/Chongqing");
        //自定义自己的错误处置函数
    	function myerror($errno,$errstr){
    		$error_info="错误信息:".$errno.$errstr;
    		error_log(date("Y-m-d G-i-s").$error_ingo."\r\n",3,"1.txt");
    	}
         set_error_handler("myerror",E_USER_WARNING);
    	 $age = 200;
    	 if($age>120){
    		  trigger_error("the age is logger!",E_USER_WARNING);
    	      exit();
    	 }
    
    ?>

    二、PHP异常处置【重点】

        

    基本语法:

        

    try{
                //可能出现错误或异常的代码
                //catch 捕获  Exception是php已定义好的异常类
            } catch(Exception $e){
                //对异常处置,方法:
                    //1、自己处置
                    //2、不处置,将其再次抛出
            }

        每日一道理
    人的生命似洪水奔流,不遇着岛屿和暗礁,难以激起美丽的浪花。

     

    处置处置程序应当包含:
    1. Try - 应用异常的函数应当位于 "try"  代码块内。如果没有触发异常,则代码将照常继承执行。但是如果异常被触发,会抛出一个异常。
    2. Throw - 这里规定如何触发异常。每一个 "throw" 必须对应最少一个 "catch"
    3. Catch - "catch" 代码块会捕获异常,并创立一个包含异常信息的对象   
    看下面的例子:
    <?php
        //创立一个抛出异常的函数
    	function checkNum($number){
    		if($number >1){
    			throw new Exception("Value must be 1 or little!<br/>");
    		}
    		return true;
    	}
    	//在 try 代码块中触发异常
    	try{
    		$num = 2;
    		checkNum($num);//AAAA
    		echo "如何抛出异常,这个将不会被执行!<br/>";
    	}catch(Exception $e){
    		//捕获异常
    		echo 'Message:'.$e->getMessage();
    	}
    	echo "继承执行<br/>";
    ?>

    当$num=2;将会抛开异常,打印下面的语句:
    Message:Value must be 1 or little!
    继承执行
    当$num=0;将会抛开异常,打印下面的语句:
    如何抛出异常,这个将不会被执行!
    继承执行
    从上面可以得出下面的结论:
     1、出捕获异常并不会干扰下面代码的执行!
     2、如果异常抛出,其后面的语句将不会被执行;

    看下面的代码我们自己设置定义异常处置函数:
    <?php
    
        function my_exception($e){
    		echo "我是顶级处置器:".$e->getMessage.$e->getline;
    	}
    	//修改默许的顶级异常处置函数
    	set_exception_handler("my_exception");
        function a1($val){
    		if($val>100){
    			//抛出异常
    			throw new Exception("val > 100!<br/>");
    		}
    	}
    	function a2($val){
    		if($val=="jsh"){
    			//抛出异常
    			throw new Exception("val  jsh!<br/>");
    		}
    	}
    
    	try{
    		a2("jsh");//这是会抛出异常
    	}catch(Exception $e){
    		//获取异常
    		echo $e->getMessage();
    		//可以继承抛出,这是会启动PHP默许的异常处置机制
    		//我们可以自己定义一个顶级异常处置函数
    		throw $e;
    	}
    ?>

    异常的规则:

    1、须要进行异常处置的代码放入try代码块内,以便捕获潜在的异常。
    2、每个try或者,throw代码块最少拥有一个catch代码。
    3、应用多个catch代码块可以捕获不同种类的异常。
       try{
            XXXXXX;
       }catch(my_exception $e){//自己定义的异常处置函数
            XXXXXX;
       }catch(Exception $3){//系统自带的异常处置函数
            XXXXX;
        } 
    4、可以在try代码块中再次抛出异常
    5,如果抛出了异常,就必须捕获他,获知应用顶级异常处置机制。

    看下面的代码示例,是在PHP手册中的,仔细获得下吧

    <?php
    /**
    * 自定义一个异常处置类
    */
    class MyException extends Exception
    {
        // 重定义构造器使 message 变为必须被指定的属性
        public function __construct($message, $code = 0) {
            // 自定义的代码
    
            // 确保全部变量都被正确赋值
            parent::__construct($message, $code);
        }
    
        // 自定义字符串输出的样式 */
        public function __toString() {
            return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
        }
    
        public function customFunction() {
            echo "A Custom function for this type of exception\n";
        }
    }
    
    
    /**
    * 创立一个用于测试异常处置机制的类
    */
    class TestException
    {
        public $var;
    
        const THROW_NONE    = 0;
        const THROW_CUSTOM  = 1;
        const THROW_DEFAULT = 2;
    
        function __construct($avalue = self::THROW_NONE) {
    
            switch ($avalue) {
                case self::THROW_CUSTOM:
                    // 抛出自定义异常
                    throw new MyException('1 is an invalid parameter', 5);
                    break;
    
                case self::THROW_DEFAULT:
                    // 抛出默许的异常
                    throw new Exception('2 isnt allowed as a parameter', 6);
                    break;
    
                default:
                    // 没有异常的情况下,创立一个对象
                    $this->var = $avalue;
                    break;
            }
        }
    }
    
    
    // 例子 1
    try {
        $o = new TestException(TestException::THROW_CUSTOM);
    } catch (MyException $e) {      // 捕获异常
        echo "Caught my exception:<br/>", $e;
        $e->customFunction();
    } catch (Exception $e) {        // 被忽略
        echo "Caught Default Exception:<br/>", $e;
    }
    /*
    // 执行后续代码
    var_dump($o);
    echo "<br/>";
    
    
    // 例子 2
    try {
        $o = new TestException(TestException::THROW_DEFAULT);
    } catch (MyException $e) {      // 不能匹配异常的种类,被忽略
        echo "Caught my exception\n", $e;
        $e->customFunction();
    } catch (Exception $e) {        // 捕获异常
        echo "Caught Default Exception\n", $e;
    }
    
    // 执行后续代码
    var_dump($o);
    echo "<br/>";
    
    
    // 例子 3
    try {
        $o = new TestException(TestException::THROW_CUSTOM);
    } catch (Exception $e) {        // 捕获异常
        echo "Default Exception caught\n", $e;
    }
    
    // 执行后续代码
    var_dump($o);
    echo "<br/>";
    
    
    // 例子 4
    try {
        $o = new TestException();
    } catch (Exception $e) {        // 没有异常,被忽略
        echo "Default Exception caught\n", $e;
    }
    */
    
    // 执行后续代码
    var_dump($o);
    echo "<br/>";
    ?>

    文章结束给大家分享下程序员的一些笑话语录: 腾讯的动作好快,2010年3月5日19时28分58秒,QQ同时在线人数1亿!刚刚看到编辑发布的文章,相差才2分钟,然后连专题页面都做出来了,他们早就预料到了吧?(其实,每人赠送10Q币,轻轻松松上两亿!)

    --------------------------------- 原创文章 By
    函数和用户
    ---------------------------------

  • 相关阅读:
    【数学】【AOJ-614】座位安排
    【乱搞】【AOJ-611】消失的5,8,9
    redis 与session
    Nginx 与 tomcat 部署网站
    linux 进程在后台执行
    印象笔记
    consul 小結
    spring boot 使用拦截器,注解 实现 权限过滤
    Springcloud/Springboot项目绑定域名,使用Nginx配置Https
    spring boot 登录认证
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3099004.html
Copyright © 2011-2022 走看看