Heim  >  Artikel  >  Backend-Entwicklung  >  Fehler und Ausnahmen, auf die PHP-Programmierer stoßen, Teil 2: Ausnahmen

Fehler und Ausnahmen, auf die PHP-Programmierer stoßen, Teil 2: Ausnahmen

不言
不言Original
2018-04-14 15:02:111561Durchsuche

In diesem Artikel werden die Fehler und Ausnahmen vorgestellt, auf die PHP-Programmierer stoßen. Jetzt können Freunde in Not darauf verweisen.

Vorheriger Artikel:In diesen Jahren traten Fehler auf Von PHP aufgetretene Ausnahmen: Fehler im vorherigen Artikel

1. Einführung und Verwendung von Ausnahmen in PHP

1.1 Ausnahmeausführungsprozess

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

Nicht erfasste Ausnahmen melden schwerwiegende Fehler : Fatal error:Uncaught exception.....

1.2 PHP-Ausnahmefunktionen

  1. PHPFängt Ausnahmen nicht aktiv ab , eine Ausnahme muss aktiv ausgelöst werden (throw) im Programm, um es zu fangen.

  2. throw wird automatisch nach oben geworfen

  3. throw wird nicht ausgeführt muss von

    gefolgt werden, andernfalls Parsing-Fehler
  4. trycatchParse error1.3 PHP integrierte Ausnahme

ist nicht wie
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();
}
Da viele Ausnahmeklassen bereitgestellt werden, werden viele Ausnahmen als Fehler behandelt. Um den Fehler in das Auslösen einer Ausnahme umzuwandeln, müssen Sie manuell

Ausnahmeobjekt

Phpin PHP integrierte Ausnahmen wie javathrow,

automatisch ausführen Ausnahmen auslösen, später kann der Code weiterhin ausgeführt werden. PDOExceptionSplFileObject

Fehler und Ausnahmen, auf die PHP-Programmierer stoßen, Teil 2: Ausnahmen

1.4 Der Unterschied zwischen Fehlern und AusnahmenFehler und Ausnahmen, auf die PHP-Programmierer stoßen, Teil 2: Ausnahmen1.4.1 Ausnahmebehandlung

Wenn eine Ausnahme ausgelöst wird, wird der Code nach

nicht weiter ausgeführt

und wird es versuchen Finden Sie passende throw Codeblöcke. Wenn die Ausnahme nicht abgefangen wird und keine Notwendigkeit besteht, für die entsprechende Verarbeitung zu verwenden, tritt ein schwerwiegender Fehler (schwerwiegender Fehler) auf und es wird „PHP“ (nicht abgefangene Ausnahme) ausgegeben. Fehlermeldung. catchset_exception_handler()1.4.2 Grundlegende Syntaxstruktur von Ausnahmen         Uncaught Exception

– Code, der Ausnahmen behandeln muss, sollte im

-Codeblock platziert werden, um potenzielle Anomalien zu erfassen . Wenn keine Ausnahme ausgelöst wird, wird die Ausführung des Codes wie gewohnt fortgesetzt. Wenn die Ausnahme jedoch ausgelöst wird, wird eine Ausnahme

ausgelöst – Dies gibt an, wie die Ausnahme ausgelöst werden soll. Jeder tryVersuch oder tryWurf
throw entspricht mindestens einem Fang. Verwenden Sie mehrere catch必须-Blöcke, um verschiedene Arten von Ausnahmen abzufangen. – Der Codeblock catch fängt die Ausnahme ab und erstellt ein Objekt mit den Ausnahmeinformationen
1.4.3 Erneut auslösen der Ausnahme catch Manchmal, wann Wenn eine Ausnahme ausgelöst wird, möchten Sie möglicherweise anders als im Standard damit umgehen. Die Ausnahme kann in einem catch

-Block erneut ausgelöst werden.

.

Skripte sollten Systemfehler vor dem Benutzer verbergen. Systemfehler mögen für Programmierer wichtig sein, aber Benutzer interessieren sich nicht dafür. Um es den Benutzern einfacher zu machen, können Sie die Ausnahme mit einer benutzerfreundlichen Nachricht erneut auslösen. Kurz gesagt: Wenn eine Ausnahme ausgelöst wird, müssen Sie sie abfangen. 注意再次抛出异常需要try{}catch{},不能直接在catch代码块中throw异常1.4.4 Der Unterschied zwischen Fehlern und Ausnahmen


Ausnahme: Das Programm läuft inkonsistent mit den Erwartungen

Fehler: Der Fehler selbst wird ausgelöst

Wenn ein Fehler auftritt, wird der Fehler selbst ausgelöst und es wird nicht automatisch eine Ausnahme ausgelöst. Ausnahmen können durch die Anweisung
    ausgelöst und durch
  • abgefangen werden. Wenn sie nicht abgefangen werden, tritt ein schwerwiegender Fehler auf. throwcatchWenn ein Fehler auftritt oder ausgelöst wird, muss das Skript sofort abgearbeitet werden. Ausnahmen können eine nach der anderen weitergegeben werden, bis sie abgefangen und dann behandelt werden.

  • Dem Fehlerauslöser ist kein Code oder Name zugeordnet. Ausnahmen können angepasst werden, um Fehlermeldungen zu verarbeiten (die Vorteile von Ausnahmen werden durch Code angezeigt, erfasst und dann verarbeitet

  • 2. Benutzerdefinierte Ausnahmeklasse

    ). 2.1 Benutzerdefinierte Ausnahmeklasse

Benutzerdefinierte Ausnahmeklasse

kann nur

den Konstruktor und
    zwei Funktionen neu schreiben
  1. Benutzerdefinierte Ausnahme Klassen können ihre eigenen Methoden hinzufügen toString

  2. Wenn es mehrere

    s gibt, wird im Allgemeinen die

    -Basisklasse am Ende platziert, und die
  3. -Basisklasse kann die aufrufen benutzerdefinierte Methoden, die durch Ausnahmeklassen definiert sind
  4. catchException

    2.2 Tipps
/**
 * 自定义异常类
 * 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öglichkeiten zum Aufzeichnen von Fehlerprotokollinformationen:
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程序员遇到的错误与异常上篇之错误

Das obige ist der detaillierte Inhalt vonFehler und Ausnahmen, auf die PHP-Programmierer stoßen, Teil 2: Ausnahmen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:PHP-Referenzen neu verstehenNächster Artikel:PHP-Referenzen neu verstehen