Maison  >  Article  >  développement back-end  >  Erreurs et exceptions rencontrées par les programmeurs PHP Partie 2 : Exceptions

Erreurs et exceptions rencontrées par les programmeurs PHP Partie 2 : Exceptions

不言
不言original
2018-04-14 15:02:111491parcourir

Cet article présente les erreurs et exceptions rencontrées par les programmeurs PHP. Maintenant, je le partage avec vous. Les amis dans le besoin peuvent s'y référer

Article précédent :Dans ces années-là, les erreurs et. exceptions rencontrées par PHP : Erreurs dans l'article précédent

1 Introduction et utilisation des exceptions en PHP

1.1 Processus d'exécution des exceptions

try
{
    // 需要进行异常处理的代码段;
    throw 语句抛出异常;
}catch( Exception $e )
{
    ... 
}
catch( Exception $e )
{
    // 处理异常
}
contine.....

Les exceptions non interceptées signaleront des erreurs fatales. : Fatal error:Uncaught exception.....

1.2 Fonctionnalités d'exception PHP

  1. PHPne détectera pas activement les exceptions , une exception doit être activement lancée (throw) au programme pour l'attraper.

  2. throw sera automatiquement lancé vers le haut. Les instructions après

  3. throw ne seront pas exécutées. doit être suivi de

    , sinon l'erreur d'analyse
  4. trycatchParse error1.3 exception intégrée PHP

n'est pas comme
try{
    $num1=3;
    $num2=0;
    if($num2==0){
        throw new Exception('0不能当作除数');
        echo 'this is a test';//看不到
    }else{
        $res=$num1/$num2;
    }
}catch(Exception $e){
    echo $e->getMessage();
}
De nombreuses classes d'exceptions sont fournies, donc de nombreuses exceptions seront traitées comme des erreurs. Pour transformer l'erreur en émission d'une exception, vous devez manuellement

Objet d'exception

PhpLes exceptions intégrées PHP telles que : javathrow,

peuvent automatiquement lancer des exceptions, plus tard Le code peut continuer à s'exécuter. PDOExceptionSplFileObject

Erreurs et exceptions rencontrées par les programmeurs PHP Partie 2 : Exceptions

1.4 La différence entre les erreurs et les exceptionsErreurs et exceptions rencontrées par les programmeurs PHP Partie 2 : Exceptions1.4.1 Gestion des exceptions

Lorsqu'une exception est levée, le code après

ne continuera pas à s'exécuter

, et tentera de trouvez un throw blocs de code correspondants. Si l'exception n'est pas interceptée et qu'il n'est pas nécessaire d'utiliser pour le traitement correspondant, alors une erreur grave (erreur fatale) se produira et "PHP" (exception non interceptée) sera généré. message d'erreur. catchset_exception_handler()1.4.2 Structure syntaxique de base des exceptions        Uncaught Exception

- Le code qui doit gérer les exceptions doit être placé dans le bloc de code

pour capturer les anomalies potentielles . Si aucune exception n'est déclenchée, le code continue son exécution comme d'habitude. Mais si l'exception est déclenchée, une exception

sera levée - Ceci précise comment déclencher l'exception. Chaque tryessai ou trylancer
throw correspond à au moins une prise. Utilisez plusieurs blocs catch必须 pour intercepter différents types d'exceptions. - Le bloc de code catch interceptera l'exception et créera un objet contenant les informations sur l'exception
1.4.3 Renvoie l'exception catch Parfois, quand Lorsqu'une exception est levée, vous souhaiterez peut-être la gérer différemment de la norme. L'exception peut être à nouveau levée dans un bloc catch

.

.

Les scripts doivent masquer les erreurs système à l'utilisateur. Les erreurs système peuvent être importantes pour les programmeurs, mais elles ne intéressent pas les utilisateurs. Pour faciliter la tâche des utilisateurs, vous pouvez relancer l'exception avec un message convivial. En bref : si une exception est levée, vous devez l'attraper. 注意再次抛出异常需要try{}catch{},不能直接在catch代码块中throw异常1.4.4 La différence entre les erreurs et les exceptions


Exception : le programme s'exécute de manière incohérente par rapport aux attentes

Erreur : l'erreur elle-même est déclenchée

Lorsqu'une erreur est rencontrée, l'erreur elle-même sera déclenchée et une exception ne sera pas automatiquement levée. Des exceptions peuvent être levées via l'instruction
    et détectées via
  • Si elles ne sont pas détectées, une erreur fatale se produira. throwcatchLorsqu'une erreur survient ou est déclenchée, le script doit être traité immédiatement. Les exceptions peuvent être ignorées une par une jusqu'à ce qu'elles soient détectées puis traitées.

  • Le déclencheur d'erreur n'a pas de code ou de nom associé. Les exceptions peuvent être personnalisées pour gérer les messages d'erreur (les avantages des exceptions sont reflétés). Elles sont générées via le code, capturées puis traitées

  • 2. Classe d'exception personnalisée

    2.1 Classe d'exception personnalisée

Classe d'exception personnalisée

ne peut

réécrire le constructeur et
    deux fonctions
  1. Exception personnalisée les classes peuvent ajouter leurs propres méthodes toString

  2. Lorsqu'il y a plusieurs

    , généralement la classe de base

    est placée à la fin, et la classe de base
  3. peut appeler la Méthodes personnalisées définies par les classes d'exception
  4. catchException

    2.2 Conseils
/**
 * 自定义异常类
 * Class MyException
 */
class MyException extends Exception
{
    public function __construct($message = "", $code = 0, Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }
    public function __toString()
    {
        $message = "<h2>出现异常了,信息如下</h2>";
        $message .= "<p>".__CLASS__."[{$this->code}]:{$this->message}</p>";
        return $message;
    }
    public function test()
    {
        echo &#39;this is a test&#39;;
    }
    public function stop()
    {
        exit(&#39;script end...&#39;);
    }
    //自定义其它方法
}

try{
    echo &#39;出现异常啦&#39;;
    throw new MyException(&#39;测试自定义异常&#39;);
}catch (MyException $exception){
    echo $exception->getMessage();
    echo $exception;
}
//会继续执行
echo &#39;continue.........&#39;;
Méthodes d'enregistrement des informations du journal des erreurs :
try{
    throw new MyException(&#39;测试自定义异常&#39;);
}catch (Exception $exception){
    echo $exception->getMessage();
    $exception->test();
} catch (MyException $exception){
    echo $exception->getMessage();
}

     (1) :file_put_contents(LOG_PATH.'error.log';, '错误信息'.' '.date('Y-m-d H:i:s')."\r\n", FILE_APPEND);

     (2) :error_log('错误信息'.' '.date('Y-m-d H:i:s')."\r\n",3,LOG_PATH.'error.log');

2.3 使用观察者模式处理异常信息

Exception_Observer.php

/**
 * 给观察者定义规范
 *
 * Interface Exception_Observer
 */
interface Exception_Observer
{
    public function update(Observable_Exception $e);
}
Observable_Exception.php

/**
 * 定义观察者
 * Class Observable_Exception
 */
class Observable_Exception extends Exception
{
    //保存观察者信息
    public static $_observers = array();
    public static function attach(Exception_Observer $observer)
    {
        self::$_observers[] = $observer;
    }
    public function __construct($message = "", $code = 0, Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
        $this->notify();
    }
    public function notify()
    {
        foreach (self::$_observers as $observer) {
            $observer->update($this);
        }
    }
}
Logging_Exception_Observer.php

/**
 * 记录错误日志
 * Class Logging_Exception_Observer
 */
class Logging_Exception_Observer implements Exception_Observer
{
    protected $_filename = __DIR__.&#39;/error_observer.log&#39;;
    public function __construct($filename = null)
    {
        if ($filename!==null && is_string($filename)){
            $this->_filename = $filename;
        }
    }

    public function update(Observable_Exception $e)
    {
        $message = "时间:".date(&#39;Y:m:d H:i:s&#39;,time()).PHP_EOL;
        $message.= "信息:".$e->getMessage().PHP_EOL;
        $message.= "追踪信息:".$e->getTraceAsString().PHP_EOL;
        $message.= "文件:".$e->getFile().PHP_EOL;
        $message.= "行号:".$e->getLine().PHP_EOL;
        error_log($message,3,$this->_filename);//写到日志中
    }
}
test.php

/**
 *测试
 */
header(&#39;content-type:text/html;charset=utf-8&#39;);
require_once &#39;Exception_Observer.php&#39;;
require_once &#39;Logging_Exception_Observer.php&#39;;
require_once &#39;Observable_Exception.php&#39;;

Observable_Exception::attach(new Logging_Exception_Observer());

class MyException extends Observable_Exception{
    public function test()
    {
        echo &#39;this is a test&#39;;
    }
}

try{
    throw new MyException(&#39;出现了异常!&#39;);
}catch (MyException $exception){
    echo $exception->getMessage();
}

三、自定义异常处理器

3.1 如何自定义异常处理器

3.1.1 自定义异常处理器

  1. 类似set_error_handler接管系统的错误处理函数,set_exception_handler接管所有没有被catch的异常

  2. restore_exception_handlerrestore_error_handler一样,本质上应该说从异常/错误处理函数栈中弹出一个。比如有一个异常处理函数,弹出一个的话,就没有异常处理函数,如果有异常没有捕获,会交由错误处理函数,如没有错误处理函数,异常最终会有系统错误处理函数处理。如果设置了2个异常处理函数,弹出一个,会交由下面一个异常处理函数处理。

/**
 * 自定义异常函数处理器
 */
header(&#39;content-type:text/html;charset=utf-8&#39;);
function exceptionHandler_1($e)
{
    echo &#39;自定义异常处理器1<br/>函数名:&#39;.__FUNCTION__.PHP_EOL;
    echo &#39;异常信息:&#39;.$e->getMessage();
}
function exceptionHandler_2($e)
{
    echo &#39;自定义异常处理器2<br/>函数名:&#39;.__FUNCTION__.PHP_EOL;
    echo &#39;异常信息:&#39;.$e->getMessage();
}

set_exception_handler(&#39;exceptionHandler_1&#39;);
//set_exception_handler(&#39;exceptionHandler_2&#39;);
//恢复到上一次定义过的异常处理函数,即exceptionHandler_1
//restore_exception_handler();
//致命错误信息
//restore_exception_handler();
throw new Exception(&#39;测试自定义异常处理器&#39;);

//自定义异常处理器,不会向下继续执行,因为throw之后不会再继续执行;try{} catch{}之后,会继续执行
//回顾:自定义错误处理器会继续执行代码,而手动抛出的错误信息不会继续执行
echo &#39;test&#39;;
/**
 * 自定义异常类处理器
 * Class ExceptionHandler
 */

class ExceptionHandler
{
    protected $_exception;
    protected $_logFile = __DIR__.&#39;/exception_handle.log&#39;;
    public function __construct(Exception $e)
    {
        $this->_exception = $e;
    }
    public static function handle(Exception $e)
    {
        $self = new self($e);
        $self->log();
        echo $self;
    }
    public function log()
    {
        error_log($this->_exception->getMessage().PHP_EOL,3,$this->_logFile);
    }

    /**
     * 魔术方法__toString()
     * 快速获取对象的字符串信息的便捷方式,直接输出对象引用时自动调用的方法。
     * @return string
     */
    public function __toString()
    {
        $message = <<<EOF
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>
            <h1>出现异常了啊啊啊啊</h1>
        </body>
        </html>
EOF;
    return $message;
    }

}
set_exception_handler(array(&#39;ExceptionHandler&#39;,&#39;handle&#39;));
/**
 * try catch不会被自定义异常处理!!!!
 */
try{
    throw new Exception(&#39;this is a test&#39;);
}catch (Exception $exception) {
    echo $exception->getMessage();
}
throw new Exception(&#39;测试自定义的异常处理器&#39;);

3.1.2 错误/异常之后是否继续执行代码问题总结

异常:

自定义异常处理器不会向下继续执行,因为throw之后不会再继续执行
try{} catch{}之后,会继续执行

错误:

自定义错误处理器会继续执行代码,而手动抛出的错误信息不会继续执行

3.2 像处理异常一样处理PHP错误

3.2.1 方式一:ErrorException

/**
 * 方式一:ErrorException错误异常类
 * @param $errno
 * @param $errstr
 * @param $errfile
 * @param $errline
 * @throws ErrorException
 */
function exception_error_handler($errno,$errstr,$errfile,$errline){

    throw new ErrorException($errstr,0,$errno,$errfile,$errline);
}

set_error_handler(&#39;exception_error_handler&#39;);

try{
    echo gettype();
}catch (Exception $exception){
    echo $exception->getMessage();
}

3.2.2 方式二:自定义异常类,继承基类Exception

/**
 * 方式二:自定义异常类
 * Class ErrorToException
 */
//显示所有的错误
error_reporting(-1);
class ErrorToException extends Exception{
    public static function handle($errno,$errstr)
    {
        throw new self($errstr,0);
    }
}

set_error_handler(array(&#39;ErrorToException&#39;,&#39;handle&#39;));
set_error_handler(array(&#39;ErrorToException&#39;,&#39;handle&#39;),E_USER_WARNING|E_WARNING);

try{
    echo $test;//notice,不会被处理
    echo gettype();//warning
    //手动触发错误
    trigger_error(&#39;test&#39;,E_USER_WARNING);
}catch (Exception $exception){
    echo $exception->getMessage();
}

3.3 PHP页面重定向实现

header(&#39;Content-type:text/html;charset=utf-8&#39;);
class ExceptionRedirectHandler{
    protected $_exception;
    protected $_logFile = __DIR__.&#39;redirect.log&#39;;
    public $redirect=&#39;404.html&#39;;
    public function __construct(Exception $e){
        $this->_exception=$e;
    }
    public static function handle(Exception $e){
        $self=new self($e);
        $self->log();
        // ob_end_clean()清除所有的输出缓冲,最后没有缓存的时候会产生通知级别的错误
        while(@ob_end_clean());
        header(&#39;HTTP/1.1 307 Temporary Redirect&#39;); //临时重定向
        header(&#39;Cache-Control:no-cache,must-revalidate&#39;);//no-cache强制向源服务器再次验证,must-revalidate可缓存但必须再向源服务器进行确认
        header(&#39;Expires: Sat, 28 Mar 2016 13:28:48 GMT&#39;); //资源失效的时间
        header(&#39;Location:&#39;.$self->redirect); //跳转
    }
    public function log(){
        error_log($this->_exception->getMessage().PHP_EOL,3,$this->_logFile);
    }
}
set_exception_handler(array(&#39;ExceptionRedirectHandler&#39;,&#39;handle&#39;));
$link=@mysqli_connect(&#39;127.0.0.1&#39;,&#39;root&#39;,&#39;1234561&#39;);
if(!$link){
    throw new Exception(&#39;数据库连接出错啦&#39;);
}

完!

参考课程视频:那些年你遇到的错误与异常

相关推荐:

PHP程序员遇到的错误与异常上篇之错误

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn