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;
        }

 

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