TP5.1开发接口时如何避免SQL错误导致的500错误

思路就是采用异常捕获的方法。如果我们不对异常进行处理,那就会被TP返回500错误,API接口的接收者会直接导致错误。场面十分难看。

如何对异常进行处理,如果你用过phpStorm2019版的话,应该会有印象,在对函数做说明的时候。 在函数上面一行输入 /** 然后回车。phpStrom会自动加上三条throws 分别是。前提是你的函数里用到了Db:: 或model 

 /**
     * @auther hotlinhao
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */

这里有三个异常,分别是 data Not Found(数据不存在) , model not found (模型不存在),Db exceptin (sql 语句错误) 。

其实我们主要用到的就是最后一个DbException . 

直接上代码。

        try{            
            $lists = Db::name('table3')->where('data','=',44)->select();
        }catch (DbException $e){ //查询SQL错误在这里处理
            //print_r($e->data());
            echo 'sql error';
        }catch (ModelNotFoundException $e){
            echo 'model not found';
        }catch (DataNotFoundException $e){
            echo 'data not found';
        }

我这里写的就是一个错误的sql查询,这时候PHP 和 TP都不会抛出异常,而是会输入 sql error . 因为这个异常已经被我们接收了。我们返回给客户一个错误信息就行了。但我们自己要把这个异常记录,便于处理。

 

还有一种情况,当PHP处理命令行代码执行的时候,或作为socket或其它长在线操作的时候是不能出现中断的。这时候的异常处理就很重要,不能因为一个未知的错误,将业务中断。

其它的异常也类似。

我们来看看TP在处理SQL操作的时候用到了哪些异常处理。

try {
            // 调试开始
            $this->debug(true);

            // 预处理
            $this->PDOStatement = $this->linkID->prepare($sql);

            // 是否为存储过程调用
            $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);

            // 参数绑定
            if ($procedure) {
                $this->bindParam($bind);
            } else {
                $this->bindValue($bind);
            }

            // 执行语句
            $this->PDOStatement->execute();

            // 调试结束
            $this->debug(false, '', true);

            if ($query && !empty($this->config['deploy']) && !empty($this->config['read_master'])) {
                $query->readMaster();
            }

            $this->numRows = $this->PDOStatement->rowCount();

            return $this->numRows;
        } catch (\PDOException $e) {
            if ($this->isBreak($e)) {
                return $this->close()->execute($sql, $bind, $query);
            }

            throw new PDOException($e, $this->config, $this->getLastsql());
        } catch (\Throwable $e) { //add ,edit 表字段不存在在这里处理
            if ($this->isBreak($e)) {
                return $this->close()->execute($sql, $bind, $query);
            }

            throw $e;
        } catch (\Exception $e) {
            if ($this->isBreak($e)) {
                return $this->close()->execute($sql, $bind, $query);
            }

            throw $e;
        }

 

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