zoukankan      html  css  js  c++  java
  • PHP-异常处理

    异常说明

    异常是推荐的错误处理方式,传统的错误处理方式要判断并一层一层返回到调用点,如下所示:

    <?php
    class Code
    {
        protected $len;
        public function make(int $len)
        {
            $this->len = $len;
            if ($this->line() === false) {
                return false;
            }
        }
        public function line()
        {
            if ($this->len > 5) {
                return false;
            }
        }
    }
    $code = new Code;
    if ($code->make(10) === false) {
        echo '验证码创建失败';
    }
    

    通过上面代码我们发布处理错误时及其不方便,需要多个判断语句。下面是改用异常的处理方式。

    <?php
    class Code
    {
        protected $len;
        public function make(int $len)
        {
            $this->len = $len;
            $this->line();
        }
        public function line()
        {
            if ($this->len > 5) {
                throw new Exception('长度不能超过五位');
            }
        }
    }
    try {
        $code = new Code;
        $code->make(10);
    } catch (Exception $e) {
        echo $e->getMessage();
    }
    

    基本使用

    try/catch

    PHP需要手动抛出异常,这与其他语言不同,异常使用try...cache触发。

    try{
    	...
    }catch(){
    	...
    }
    

    try 代码块中对出现的错误可以抛出异常,下面是手动抛出异常的方法。

    throw new Exception($message,$code)
    

    catch 用于接收异常,可以设置多个catch 代码块,参数为 Exception 类或继承于 Exception 的类。

    <?php
    class ValidateException extends Exception
    { }
    try {
        throw new ValidateException('is exception', 403);
    } catch (ValidateException $e) {
        echo 'httpException' . $e->getMessage() . ';code:' . $e->getCode();
    } catch (Exception $e) {
        echo $e->getMessage();
    } finally {
        echo '无论是否抛出异常都将执行' . ';code:' . $e->getCode();;
    }
    

    finally

    finally需要放在 catch 后,finally无论是否抛出异常都会执行。

    ...
    } catch (Exception $e) {
        echo $e->getMessage();
    } finally {
        echo '无论是否抛出异常都将执行';
    }
    ...
    

    Throwable

    异常和部分错误实现了Throwable接口。

    Exception implements Throwable {
     	...
    }
    

    部分错误也实现了 Throwable接口

    Error implements Throwable {
    	...
    }
    

    比如以下错误

    • ArithmeticError 数学运算错误
    • DivisionByZeroError 除数为0的错误
    • ParseError 解析代码时发生错误如调用 eval 函数时
    • TypeError 函数参数类型错误,函数返回值错误

    异常类

    基类方法

    PHP为异常处理提供了基础类 Exception,Exception` 类可用方法如下:

    方法 说明 重写
    getFile 产生异常错误的文件 NO,final
    getCode 错误码 NO,final
    getLine 错误行号 NO,final
    getMessage 错误消息 NO,final
    __toString 对象转字符串后输出内容 YES
    <?php
    class ValidateException extends Exception
    {
    	//对象转字符串时执行的魔术方法
        public function __toString()
        {
            return $this->getFile();
        }
    }
    try {
        throw new ValidateException('is exception', 403);
    } catch (ValidateException $e) {
        echo "文件:" . $e->getFile() . "<hr/>";
        echo "消息:" . $e->getMessage() . "<hr/>";
        echo "错误码:" . $e->getCode() . "<hr/>";
        echo "错误行:" . $e->getLine() . "<hr/>";
        echo $e . "<hr/>";
    }
    

    异常实例

    实际开发中需要根据不同业务创建处理错误的异常类,推荐使用异常来处理错误而不是PHP的错误处理机制。

    因为代码量比较大,大家请查看视频教程来学习。

    自定义异常

    下面是通过实例讲解自定义异常的使用方法。

    目录结构

    app
    -- Exceptions
    	-- ValidateException.php
    	-- ViewException.php
    -- Servers
    	-- Validate.php
    	-- View.php
    -- vendor
    -- view
    	-- error.blade.php
    	-- index.blade.php
    	-- success.blade.php
    bootstrap.php
    composer.json
    controller.php
    index.php
    

    文件内容

    appExceptionsValidateException.php

    <?php
    namespace AppExceptions;
    
    class ValidateException extends Exception
    {
        public function render()
        {
            $_SESSION['VALIDATE_ERROR'] = '表单参数错误';
            header('location:index.php');
        }
    }
    

    appExceptionsViewException.php

    <?php
    namespace AppExceptions;
    
    use AppServersView;
    
    class ViewException extends Exception
    {
        public function render()
        {
            View::make('error', ['error' => $this->getMessage()]);
        }
    }
    

    appServersValidate.php

    <?php
    namespace AppServers;
    
    use AppExceptionsValidateException;
    
    class Validate
    {
        public static function make()
        {
            $_SESSION['VALIDATE_ERROR'] = '';
            if (empty($_POST['title'])) {
                throw new ValidateException('表单错误');
            }
        }
    }
    

    appServersView.php

    <?php
    namespace AppServers;
    
    use AppExceptionsViewException;
    
    class View
    {
        public static function make(string $tpl, array $vars = [])
        {
            $file = 'view/' . $tpl . '.blade.php';
            if (!is_file($file)) {
                throw new ViewException($file . '模板不存在');
            }
            include $file;
        }
    }
    

    appviewerror.blade.php

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <h1><?php echo $vars['error'];?></h1>
    </body>
    </html>
    

    appviewindex.blade.php

    <?php if(isset($_SESSION['VALIDATE_ERROR'])):?>
    <?php echo $_SESSION['VALIDATE_ERROR'];?>
    <?php endif;?>
        <form method="post" action="controller.php">
            <input type="text" name="title">
            <button>提交</button>
        </form>
    

    appviewerror.blade.php

    <h1>操作成功</h1>
    

    appootstrap.php

    <?php
    session_start();
    include 'vendor/autoload.php';
    class Boot
    {
        public function init()
        {
            set_exception_handler([$this, 'exception']);
        }
        public function exception($e)
        {
            if (method_exists($e, 'render')) {
                $e->render();
            }
        }
    }
    (new Boot)->init();
    

    composer.json

    {
        "name": "hd/app",
        "authors": [
            {
                "name": "houdunren.com",
                "email": "2300071698@qq.com"
            }
        ],
        "autoload": {
            "psr-4": {
                "App\": "."
            }
        },
        "require": {}
    }
    

    controller.php

    <?php
    include 'bootstrap.php';
    use AppServersValidate;
    use AppServersView;
    
    include 'vendor/autoload.php';
    // try {
    Validate::make();
    View::make('success');
    // } catch (ValidateException $e) {
    //     $e->render();
    // } catch (ViewException $e) {
    //     $e->render();
    // }
    

    index.php

    <?php
    namespace App;
    
    include 'bootstrap.php';
    use AppServersView;
    
    View::make('index');
    
  • 相关阅读:
    Django 同步数据库的时候app中的models的表没有成功创建
    mysql 个人博客应用的建表和相关查询
    lambda(),map(),filter()
    用小白鼠找毒药
    python 汉诺塔问题
    灰色预测
    python可视化图标
    exel数据可视化
    543. 二叉树的直径
    236. 二叉树的最近公共祖先
  • 原文地址:https://www.cnblogs.com/pengcode/p/12585422.html
Copyright © 2011-2022 走看看