ThinkPHP 模型 (Model) 內建三大自動機制,在 create()、add()、save() 等操作前自動執行,大幅減少控制器樣板代碼。
$_validate定義驗證規則陣列,格式:
array(
// array('驗證字段', '驗證規則', '錯誤提示', '驗證條件', '附加規則', '驗證時間')
array('user_name', 'require', '用戶名必須填寫!'),
array('user_name', '6,12', '用戶名長度 6-12 位', 0, 'length'),
array('real_name', 'require', '真實姓名必填!'),
array('password', 'require', '密碼必填!'),
array('password', '8,12', '密碼長度 8-12 位', 0, 'length'),
array('rePassword', 'require', '確認密碼必填!'),
array('password', 'rePassword', '兩次密碼不一致', 0, 'confirm'),
array('email', 'require', '郵箱必填'),
array('email', 'email', '郵箱格式錯誤!', 1), // 條件 1: 值不為空時驗證
array('verify', 'require', '驗證碼必填'),
array('code', 'checkCode', '驗證碼錯誤', 0, 'callback'), // 回調模型方法
)
| 規則 | 說明 | 驗證規則欄位寫法 |
|---|---|---|
regex | 正則驗證 | 正則表達式,如 /^1\d{10}$/ |
function | 函數驗證 | 函數名,如 check_mobile |
callback | 模型方法回調 | 方法名,如 checkCode (接收字段值參數) |
confirm | 兩字段值相等 | 目標字段名,如 rePassword |
equal | 等於指定值 | 目標值 |
in | 在範圍內 | 陣列,如 array(1,2,3) |
unique | 唯一性 (查庫) | 字段名 (會自動查詢同表該字段是否存在) |
require | 必填 (內置) | 無需附加規則 |
email/url/number/... | 內置格式驗證 | 無需附加規則 |
0 (預設):存在字段即驗證 (含空字串)1:值不為空時驗證2:值為空時驗證3:Model::MODEL_BOTH (新增/編輯皆驗證,等同於 0)Model::MODEL_INSERT (1):新增時驗證Model::MODEL_UPDATE (2):編輯時驗證Model::MODEL_BOTH (3):全部驗證 (預設)$_auto格式:array('填充字段', '填充內容', '填充條件', '附加規則')
protected $_auto = array(
array('password', 'md5', 3, 'function'), // 新增/編輯皆對 password 執行 md5()
array('age', 'deal_int', 3, 'callback'), // 回調模型方法 deal_int($value)
// array('create_time', 'time', 1, 'function'), // 僅新增時填充 time()
// array('ip', 'get_client_ip', 1, 'function'), // 僅新增時獲取客戶端 IP
);
function:PHP 內置/自定義函數,接收字段值 (若有) 返回新值callback:模型方法,function deal_int($data) { return (int)$data; }field:用其他字段值填充,array('full_name', 'first_name', 1, 'field')string:直接字串填充 (預設)ignore:忽略 (不填充)$_map解決表單字段名與資料庫字段名不一致問題:
protected $_map = array(
'username' => 'user_name', // 表單 username → 數據庫 user_name
'realname' => 'real_name', // 表單 realname → 數據庫 real_name
// 格式:'表單字段' => '數據庫字段'
);
啟用後,create() 會自動將 $_POST['username'] 映射為 data['user_name']。
<?php
class UserModel extends Model {
protected $_validate = array(
array('username', 'require', '用戶名必填'),
array('username', '4,16', '用戶名 4-16 位', 0, 'length'),
array('email', 'email', '郵箱格式錯誤', 1),
array('password', 'require', '密碼必填', 1),
array('password', '6,20', '密碼 6-20 位', 1, 'length'),
array('repass', 'password', '密碼不一致', 1, 'confirm'),
array('verify', 'checkVerify', '驗證碼錯誤', 1, 'callback'),
);
protected $_auto = array(
array('password', 'md5', Model::MODEL_BOTH, 'function'),
array('reg_time', 'time', Model::MODEL_INSERT, 'function'),
array('reg_ip', 'get_client_ip', Model::MODEL_INSERT, 'function'),
array('status', 1, Model::MODEL_INSERT, 'string'),
);
protected $_map = array(
'username' => 'user_name',
'email' => 'user_email',
);
protected function checkVerify($code) {
return (isset($_SESSION['verify']) && strtoupper($code) === $_SESSION['verify']);
}
}
?>
public function register() {
$User = D('User');
if ($User->create()) { // 自動驗證 + 自動完成 + 字段映射
if ($User->add()) {
$this->success('註冊成功');
} else {
$this->error('寫入失敗');
}
} else {
$this->error($User->getError()); // 獲取驗證失敗提示
}
}
$_auto,控制器保持乾淨unique 驗證會產生額外查詢,高併發場景考慮資料庫唯一索引 + 捕獲異常validate 驗證器類,語法不同,遷移時注意