思路就是采用异常捕获的方法。如果我们不对异常进行处理,那就会被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;
}