思路就是採用異常捕獲的方法。如果我們不對異常進行處理,那就會被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;
}