美文网首页
PHP七天系列之异常处理

PHP七天系列之异常处理

作者: PFinal南丞 | 来源:发表于2020-04-24 21:06 被阅读0次

    异常说明


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

    <?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 '无论是否抛出异常都将执行';
    }
    ...
    

    异常类


    基类方法

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

    方法 说明 重写
    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
    

    文件内容

    app\Exceptions\ValidateException.php

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

    app\Exceptions\ViewException.php

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

    app\Servers\Validate.php

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

    app\Servers\View.php

    <?php
    namespace App\Servers;
    
    use App\Exceptions\ViewException;
    
    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;
        }
    }
    

    app\view\error.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>
    

    app\view\index.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>
    

    app\view\error.blade.php

    <h1>操作成功</h1>
    

    app\bootstrap.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": "pfinalClub.com",
                "email": "lampxiezi@163.com"
            }
        ],
        "autoload": {
            "psr-4": {
                "App\\": "."
            }
        },
        "require": {}
    }
    

    controller.php

    <?php
    include 'bootstrap.php';
    use App\Servers\Validate;
    use App\Servers\View;
    
    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 App\Servers\View;
    
    View::make('index');
    

    相关文章

      网友评论

          本文标题:PHP七天系列之异常处理

          本文链接:https://www.haomeiwen.com/subject/rbryvhtx.html