作者在項目裡寫一個簡單的建立問題介面時,一不小心就踩到了ThinkPHP的兩個坑。將它稱之為坑,實則是對文檔的不熟悉。介面代碼如下:
public function createProblems(){ $problems = I('json.'); if (empty($problems)) { $this->error($problems, 'json格式不符合規範'); } foreach ($problems as $problem) { $data = D('Problem')->create($problem, self::OP_INSERT); if (!$data) { $this->error($problem, D('Problem')->getError()); } $temp[] = $data; } $ret = D('Problem', 'Service')->addProblems($temp); if ($ret === false) { $this->error(null, '匯入失敗'); } $this->success(null);}
介面完成的功能是大量建立問題,參數為json數組,addProblem()方法中就是一個addAll操作。
第一個坑-自動填滿
使用自動填滿可能會覆蓋表單提交項目。其目的是為了防止表單非法提交欄位。使用Model類的create方法建立資料對象的時候會自動進行表單資料處理。
官方文檔明確說了自動填滿會覆蓋表單,所以即使你post過來的參數中給出了具體數值,使用create方法之後也可能會被覆蓋。千萬注意!!!
第二個坑-addAll方法
addAll方法中不能出現null值,否則其他資料會自動向前移動,導致添加失敗。舉例:
[ { "appId": 1, "serviceId": 2, "createUser":null, "status": 1, "priority": 2 }]
其中,createUser欄位為null,插入時的sql語句會變成insert into va_problem (appId, serviceId, createUser, status, priority)values (1, 2, 1, 2)。null值沒了,導致插入失敗,這應該是ThinkPHP3.2.3的一個bug。這篇部落格有相關的討論。
引入坑的過程
problemModel裡面有對createUser做自動填滿。
通過api建立問題時,首先自動填滿會覆蓋,所以表單中的createUser值失效,這是第一個坑。然後,由於自動填滿createUser調用的是get_username()函數,通過api調用時,session(username)取不到值,所以create之後欄位變成"createUser":null,引入了第二個坑。