程序开发的一些常规套路(一)

进入软件开发许久,期间做过Android,玩过opencv,做过小程序,写过TP5的接口。现在将一些软件开发上的常规套路分享给大家。服务器方面将会以TP5框架为例,客户端则以微信小程序为例。

服务器方面

(以TP5为例)
服务器开发人员主要的工作就是写接口了。包括处理客户端传递过来的数据,以及将数据库中的信息传递给客户端。个人理解,项目开发之前,首先要做的就是设计数据库,理解表与表之间的关系,这一点对服务器开发人员尤为重要,因为接口中的内容归根揭底都是表与表之间的关系。

无论是后台服务器还是前台客户端,项目开发的第一步就是写好基类,将基本的框架功能搭建好。也许公司有框架,但是你不能否认这一步真的能为后面的工作节省很多的时间。接下来,从TP5的角度开发,说说我自己在开发上的一些常规套路。

大家都知道,服务器在无论在线下开发测试的时候,还是在线上都会遇到异常,在我们公司,是通过客户端可解析得json字符串来向客户端反馈的。一般,把可预计的异常的都抛出去,在客户端进行异常处理。只有在服务器按计划正确执行了的代码,才能在客户端进行正确的响应。在这里用到的方法就是抽取异常基类以及定义全局异常了。
抽取异常基类
首先我们来看看在客户端显示的数据是怎么样的。
当服务器遇到异常时,响应的数据。

异常显示

服务器正确响应时反馈给客户端的数据
image.png

这里先来说说,响应异常时的处理方法。可以看出异常时json字符串中有statue msg errorCode 以及 url,我们在自己写的BaseException(继承TP5中的Exception)定义这几个字段。会在自定义全局HandLer中遇上。下面来具体看看代码
正确响应时候调用的方法,我们可以将它抽取到基类中,当然也可以定义公共php文件common.php

function  show($status, $message,$data=array()) {
    $reuslt = array(
        'status' => $status,
        'msg' => $message,
        'data' => $data,
    );

    exit(json_encode($reuslt));
}
class BaseException extends Exception
    {
        //以下定义的变量 在全局异常处理类中会用到
        public $status=0;//服务器状态码 0代表异常,1代表正确响应
        public $code =400;//Http状态码 404 .402
        public $msg="param error";//错误具体信息
        public $errorCode=10000;//自定义错误码

        /**
         * 构造函数,接收一个关联数组
         * @param array $params 关联数组只应包含code、msg和errorCode,且不应该是空值
         */
        public function __construct($params=[])
        {
            if(!is_array($params)){
                return;
            }
            if(array_key_exists('code',$params)){
                $this->code = $params['code'];//将传递过来的值赋值给成员变量(java里的说法)
            }
            if(array_key_exists('msg',$params)){
                $this->msg = $params['msg'];
            }
            if(array_key_exists('errorCode',$params)){
                $this->errorCode = $params['errorCode'];
            }
            if(array_key_exists('status',$params)){
                $this->errorCode = $params['status'];
            }
        }
    }

需要注意的是BaseException的构造方法,这里运用的比较巧妙,通过这种方式,我们可以很直接的在BaseException中自定义传递给客户端的参数,方便前台开发人员做出正确的响应。
示例

throw new BaseException([
            "msg"=>"测试异常",
            "statue"=>1,
            "errorCode"=>10011]);
示例效果

定义全局异常处理
当然想要达到以上的效果,只定义基类异常还是不行的。还需要另外自定义全局异常处理。在TP5框架当中的config.php文件中有一个exception_handle变量,用来指定服务器异常时要调用的handler处理方法。我们可以将它的路径设置为我们自己所写的继承了Handler的类来实现全局异常。

   // 异常处理handle类 留空使用 \think\exception\Handle
    'exception_handle'       => 'app\lib\exception\ExceptionHandler',//自定义异常路径

ExceptionHandler是我们自定义的异常,继承自TP5框架的Handler,而在Hanler中有一个render方法,在其中可以接受来自后台抛出的Exception,从而做出对客户端的响应。我们可以在子类中重定义这个方法,输出json字符串,来达到上面示例中的效果。下面来看看具体代码。

class ExceptionHandler extends Handle
{
    //以下定义的变量是响应给客户端的
    public $code;
    public $msg;
    public $errorCode;
    public $status;

    public function render(Exception $e)
    {//传递过来的Exception是程序捕获的到,可以是我们自己人为抛出
        if ($e instanceof BaseException) {
            //进行判断如果是我们自定义的异常,则输出自定义异常信息
            $this->code = $e->code;//将BaseException中的值赋值给成员变量,最后进行输出
            $this->msg = $e->msg;
            $this->errorCode = $e->errorCode;
            $this->status = $e->status;
        } else {
            $switch = true;
            if (config('app_debug')) {//判断是否为调试模式,
                //返回默认界面
                return parent::render($e);
            } else {
                //返回json数据
                $this->code = 500;
                $this->msg = "服务器内部错误";
                $this->errorCode = 999;
                $this->status = 0;
                $this->recordLog($e);
            }

        }
        $request = Request::instance();
        $result = [
            "status" => $this->status,
            "msg" => $this->msg,
            "errorCode" => $this->errorCode,
            "url" => $request->url()
        ];

        return json($result, $this->code);
    }

    //记录日志方法
    private function recordLog(Exception $e)
    {
        Log::init([
            'type' => 'File',
            'path' => LOG_PATH,
            'level' => ['error'],
        ]);
        Log::record($e->getMessage(), 'error');
    }
}

由于篇幅受限,就先说到这里。喜欢的可以点个关注,下期继续。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章