<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] * * * * * #1 數據驗證器 >>數據驗證 >對客戶端發起請求的數據進行驗證過濾處理 >>數據驗證接口包括 >驗證規則注冊接口 >驗證規則使用接口 ## 1-1 數據驗證器創建 ### Validate::make() >>單例模式,創建全局唯一驗證器實例對象 ~~~ public static function make($rules = [], $message = []) { if (is_null(self::$instance)) { self::$instance = new self($rules, $message); } return self::$instance; } ~~~ ### Validate->__construct() >>構造函數,驗證器構造函數 ~~~ public function __construct(array $rules = [], $message = []) { $this->rule = array_merge($this->rule, $rules); $this->message = array_merge($this->message, $message); } ~~~ # 2 數據驗證使用接口 >>使用注冊的(驗證規則) 對 (請求數據的字段) 進行驗證 >驗證器可以在控制器,模型的數據處理過程中使用。 ## 2-1 數據字段設置驗證規則 >>在驗證器構造函數的參數選項中注冊需要驗證的字段對應的規則 ~~~ $rules = [ 'name' => 'require|max:25', 'age' => 'number|between:1,120', ]; $validate = new Validate($rules); ~~~ >如上表示對數據的name字段驗證require和max:25兩個規則 >age的字段驗證nnumber和between:1,120兩個規則 ## 2-2 數據字段使用驗證規則 >>調用驗證的check()方法對數據相應字段進行驗證 ~~~ $rule = [ 'name' => 'require|max:25', 'age' => 'number|between:1,120', 'email' => 'email', ]; $msg = [ 'name.require' => '名稱必須', 'name.max' => '名稱最多不能超過25個字符', 'age.number' => '年齡必須是數字', 'age.between' => '年齡只能在1-120之間', 'email' => '郵箱格式錯誤', ]; $data = [ 'name' => 'thinkphp', 'age' => 10, 'email' => 'thinkphp@qq.com', ]; $validate = new Validate($rule, $msg); $result = $validate->check($data); ~~~ ## 2-3 控制器調用驗證 >> 繼承think\Controller的控制器,可以調用validate方法進行驗證 ~~~ $result = $this->validate( [ 'name' => 'thinkphp', 'email' => 'thinkphp@qq.com', ], [ 'name' => 'require|max:25', 'email' => 'email', ]); if(true !== $result){ // 驗證失敗 輸出錯誤信息 dump($result); } ~~~ > 也可以調用外部定義的驗證器子類 ~~~ ; 創建驗證器子類 use think\Validate; class User extends Validate { protected $rule = [ 'name' => 'require|max:25', 'email' => 'email', ]; protected $message = [ 'name.require' => '用戶名必須', 'email' => '郵箱格式錯誤', ]; protected $scene = [ 'add' => ['name','email'], 'edit' => ['email'], ]; } ; 調用驗證器子類 $result = $this->validate($data,'User'); if(true !== $result){ // 驗證失敗 輸出錯誤信息 dump($result); } ~~~ ## 2-4 模型調用驗證 >> 也可在模型中調用驗證器對數據特定字段進行驗證 ~~~ $User = new User; $result = $User->validate( [ 'name' => 'require|max:25', 'email' => 'email', ], [ 'name.require' => '名稱必須', 'name.max' => '名稱最多不能超過25個字符', 'email' => '郵箱格式錯誤', ] )->save($data); if(false === $result){ // 驗證失敗 輸出錯誤信息 dump($User->getError()); } ~~~ >>對于驗證器子類與數據模型同名的可以如下調用驗證器 ~~~ ;創建同名驗證器 namespace app\index\validate; use think\Validate; class User extends Validate { protected $rule = [ 'name' => 'require|max:25', 'email' => 'email', ]; protected $message = [ 'name.require' => '用戶名必須', 'email' => '郵箱格式錯誤', ]; protected $scene = [ 'add' => ['name','email'], 'edit' => ['email'], ]; } ;同名模型調用驗證器 $User = new User; // 調用當前模型對應的User驗證器類進行數據驗證 $result = $User->validate(true)->save($data); if(false === $result){ // 驗證失敗 輸出錯誤信息 dump($User->getError()); } ~~~ >>如果驗證器名與模型名不同,則如下調用 ~~~ $User = new User; // 調用Member驗證器類進行數據驗證 $result = $User->validate('Member')->save($data); if(false === $result){ // 驗證失敗 輸出錯誤信息 dump($User->getError()); } ~~~ ## 2-5 驗證接口 ### $validate->check() >>對數據$data,調用$rule進行驗證處理,也可以傳入場景標識 ~~~ public function check($data, $rules = [], $scene = '') { $this->error = []; if (empty($rules)) { // 讀取驗證規則 $rules = $this->rule; } // 分析驗證規則 $scene = $this->getScene($scene); if (is_array($scene)) { // 處理場景驗證字段 $change = []; $array = []; foreach ($scene as $k => $val) { if (is_numeric($k)) { $array[] = $val; } else { $array[] = $k; $change[$k] = $val; } } } foreach ($rules as $key => $item) { // field => rule1|rule2... field=>['rule1','rule2',...] if (is_numeric($key)) { // [field,rule1|rule2,msg1|msg2] $key = $item[0]; $rule = $item[1]; if (isset($item[2])) { $msg = is_string($item[2]) ? explode('|', $item[2]) : $item[2]; } else { $msg = []; } } else { $rule = $item; $msg = []; } if (strpos($key, '|')) { // 字段|描述 用于指定屬性名稱 list($key, $title) = explode('|', $key); } else { $title = $key; } // 場景檢測 if (!empty($scene)) { if ($scene instanceof \Closure && !call_user_func_array($scene, [$key, $data])) { continue; } elseif (is_array($scene)) { if (!in_array($key, $array)) { continue; } elseif (isset($change[$key])) { // 重載某個驗證規則 $rule = $change[$key]; } } } // 獲取數據 支持二維數組 $value = $this->getDataValue($data, $key); // 字段驗證 $result = $this->checkItem($key, $value, $rule, $data, $title, $msg); if (true !== $result) { // 沒有返回true 則表示驗證失敗 if (!empty($this->batch)) { // 批量驗證 if (is_array($result)) { $this->error = array_merge($this->error, $result); } else { $this->error[$key] = $result; } } else { $this->error = $result; return false; } } } return !empty($this->error) ? false : true; } ~~~ ### $validate->checkItem() >>對單個數據字典進行驗證 ~~~ protected function checkItem($field, $value, $rules, $data, $title = '', $msg = []) { if ($rules instanceof \Closure) { // 匿名函數驗證 支持傳入當前字段和所有字段兩個數據 $result = call_user_func_array($rules, [$value, $data]); } else { // 支持多規則驗證 require|in:a,b,c|... 或者 ['require','in'=>'a,b,c',...] if (is_string($rules)) { $rules = explode('|', $rules); } $i = 0; foreach ($rules as $key => $rule) { if ($rule instanceof \Closure) { $result = call_user_func_array($rule, [$value, $data]); } else { // 判斷驗證類型 if (is_numeric($key) && strpos($rule, ':')) { list($type, $rule) = explode(':', $rule, 2); if (isset($this->alias[$type])) { // 判斷別名 $type = $this->alias[$type]; } $info = $type; } elseif (is_numeric($key)) { $type = 'is'; $info = $rule; } else { $info = $type = $key; } // 如果不是require 有數據才會行驗證 if (0 === strpos($info, 'require') || (!is_null($value) && '' !== $value)) { // 驗證類型 $callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type]; // 驗證數據 $result = call_user_func_array($callback, [$value, $rule, $data, $field]); } else { $result = true; } } if (false === $result) { // 驗證失敗 返回錯誤信息 if (isset($msg[$i])) { $message = $msg[$i]; } else { $message = $this->getRuleMsg($field, $title, $info, $rule); } return $message; } elseif (true !== $result) { // 返回自定義錯誤信息 return $result; } $i++; } } return true !== $result ? $result : true; } ~~~ #3 數據驗證注冊接口 >>注冊接口用來注冊字段的驗證規則類型 >內置的驗證規則類型實現為驗證器類Validate的相應方法,如gt,lt等 ## 3-1 驗證規則注冊 ### Validate::extend() >> 注冊驗證規則類型,調用extend()注冊特定類型驗證規則與相應的回調方法 ~~~ public static function extend($type, $callback = null) { if (is_array($type)) { self::$type = array_merge(self::$type, $type); } else { self::$type[$type] = $callback; } } ~~~ ### Validate::setTypeMsg() >> 注冊驗證規則類型的提示信息 ,可以獲取和修改特定類型驗證規則的提示信息 ~~~ public static function setTypeMsg($type, $msg = null) { if (is_array($type)) { self::$typeMsg = array_merge(self::$typeMsg, $type); } else { self::$typeMsg[$type] = $msg; } } ~~~ ### Validate->message() >> 注冊特定字段的特定類型驗證規則提示信息 ~~~ public function message($name, $message = '') { if (is_array($name)) { $this->message = array_merge($this->message, $name); } else { $this->message[$name] = $message; } return $this; } ~~~ >使用方法如下 ~~~ $rule = [ 'name' => 'require|max:25', 'age' => 'number|between:1,120', 'email' => 'email', ]; $msg = [ 'name.require' => '名稱必須', 'name.max' => '名稱最多不能超過25個字符', 'age.number' => '年齡必須是數字', 'age.between' => '年齡必須在1~120之間', 'email' => '郵箱格式錯誤', ]; $data = [ 'name' => 'thinkphp', 'age' => 121, 'email' => 'thinkphp@qq.com', ]; $validate = new Validate($rule); ;注冊特定數據字段的驗證提示信息 $validate->message($msg); $result = $validate->check($data); if(!$result){ echo $validate->getError(); } ~~~ ## 3-2 內置驗證規則 >>Validate類內置了基礎類型的驗證規則 ### $validate->confirm() >> 驗證字段的是等于某個值 ~~~ protected function confirm($value, $rule, $data) { return $this->getDataValue($data, $rule) == $value; } ~~~ ### $validate->different() >> 驗證字段是否不等于某個值 ~~~ protected function different($value, $rule, $data) { return $this->getDataValue($data, $rule) != $value; } ~~~ ### $validate->egt() >>驗證字段是否大于等于某個值 ~~~ protected function egt($value, $rule) { return $value >= $rule; } ~~~ ### $validate->gt() >> 驗證字段是否等于某個值 ~~~ protected function gt($value, $rule) { return $value > $rule; } ~~~ ### $validate->elt() >> 驗證字段是否小于等于某個值 ~~~ protected function elt($value, $rule) { return $value <= $rule; } ~~~ ### $validate->lt() >> 驗證字段是否小于某個值 ~~~ protected function lt($value, $rule) { return $value < $rule; } ~~~ ### $validate->eq() >> 驗證字段是否等于某個值 ~~~ protected function eq($value, $rule) { return $value == $rule; } ~~~ ### $validate->is() >> 驗證字段是否為有效格式 ~~~ protected function is($value, $rule, $data = []) { switch ($rule) { case 'require': // 必須 $result = !empty($value) || '0' == $value; break; case 'accepted': // 接受 $result = in_array($value, ['1', 'on', 'yes']); break; case 'date': // 是否是一個有效日期 $result = false !== strtotime($value); break; case 'alpha': // 只允許字母 $result = $this->regex($value, '/^[A-Za-z]+$/'); break; case 'alphaNum': // 只允許字母和數字 $result = $this->regex($value, '/^[A-Za-z0-9]+$/'); break; case 'alphaDash': // 只允許字母、數字和下劃線 破折號 $result = $this->regex($value, '/^[A-Za-z0-9\-\_]+$/'); break; case 'chs': // 只允許漢字 $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}]+$/u'); break; case 'chsAlpha': // 只允許漢字、字母 $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}a-zA-Z]+$/u'); break; case 'chsAlphaNum': // 只允許漢字、字母和數字 $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9]+$/u'); break; case 'chsDash': // 只允許漢字、字母、數字和下劃線_及破折號- $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9\_\-]+$/u'); break; case 'activeUrl': // 是否為有效的網址 $result = checkdnsrr($value); break; case 'ip': // 是否為IP地址 $result = $this->filter($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6); break; case 'url': // 是否為一個URL地址 $result = $this->filter($value, FILTER_VALIDATE_URL); break; case 'float': // 是否為float $result = $this->filter($value, FILTER_VALIDATE_FLOAT); break; case 'number': $result = is_numeric($value); break; case 'integer': // 是否為整型 $result = $this->filter($value, FILTER_VALIDATE_INT); break; case 'email': // 是否為郵箱地址 $result = $this->filter($value, FILTER_VALIDATE_EMAIL); break; case 'boolean': // 是否為布爾值 $result = in_array($value, [0, 1, true, false]); break; case 'array': // 是否為數組 $result = is_array($value); break; case 'file': $result = $value instanceof File; break; case 'image': $result = $value instanceof File && in_array($this->getImageType($value->getRealPath()), [1, 2, 3, 6]); break; case 'token': $result = $this->token($value, '__token__', $data); break; default: if (isset(self::$type[$rule])) { // 注冊的驗證規則 $result = call_user_func_array(self::$type[$rule], [$value]); } else { // 正則驗證 $result = $this->regex($value, $rule); } } return $result; } ~~~ ### $validate->getImageType() >>判斷圖像類型 ~~~ protected function getImageType($image) { if (function_exists('exif_imagetype')) { return exif_imagetype($image); } else { $info = getimagesize($image); return $info[2]; } } ~~~ ### $validate->activeUrl() >> 判斷是否為合格的域名或IP ~~~ protected function activeUrl($value, $rule) { return checkdnsrr($value, $rule); } ~~~ ### $validate->ip() >> 驗證是否為有效IP ~~~ protected function ip($value, $rule) { if (!in_array($rule, ['ipv4', 'ipv6'])) { $rule = 'ipv4'; } return $this->filter($value, FILTER_VALIDATE_IP, 'ipv6' == $rule ? FILTER_FLAG_IPV6 : FILTER_FLAG_IPV4); } ~~~ ### $validate->fileExt() >>驗證上傳文件的后綴 ~~~ protected function fileExt($file, $rule) { if (!($file instanceof File)) { return false; } if (is_string($rule)) { $rule = explode(',', $rule); } if (is_array($file)) { foreach ($file as $item) { if (!$item->checkExt($rule)) { return false; } } return true; } else { return $file->checkExt($rule); } } ~~~ ### $validate->fileMime() >> 驗證上傳文件類型 ~~~ protected function fileMime($file, $rule) { if (!($file instanceof File)) { return false; } if (is_string($rule)) { $rule = explode(',', $rule); } if (is_array($file)) { foreach ($file as $item) { if (!$item->checkMime($rule)) { return false; } } return true; } else { return $file->checkMime($rule); } } ~~~ ### $validate->fileSize() >>驗證上傳文件大小 ~~~ protected function fileSize($file, $rule) { if (!($file instanceof File)) { return false; } if (is_array($file)) { foreach ($file as $item) { if (!$item->checkSize($rule)) { return false; } } return true; } else { return $file->checkSize($rule); } } ~~~ ### $validate->image() >>驗證上傳圖片的大小與類型 ~~~ protected function image($file, $rule) { if (!($file instanceof File)) { return false; } $rule = explode(',', $rule); list($width, $height, $type) = getimagesize($file->getRealPath()); if (isset($rule[2])) { $imageType = strtolower($rule[2]); if ('jpeg' == $imageType) { $imageType = 'jpg'; } if (image_type_to_extension($type, false) != $imageType) { return false; } } list($w, $h) = $rule; return $w == $width && $h == $height; } ~~~ ### $validate->method() >>驗證當前請求類型 ~~~ protected function method($value, $rule) { $method = Request::instance()->method(); return strtoupper($rule) == $method; } ~~~ ### $validate->deteFormat() >> 驗證時間和日期格式 ~~~ protected function dateFormat($value, $rule) { $info = date_parse_from_format($rule, $value); return 0 == $info['warning_count'] && 0 == $info['error_count']; } ~~~ ### $validate->unique() >> 驗證字段是否唯一 ~~~ protected function unique($value, $rule, $data, $field) { if (is_string($rule)) { $rule = explode(',', $rule); } $db = Db::name($rule[0]); $key = isset($rule[1]) ? $rule[1] : $field; if (strpos($key, '^')) { // 支持多個字段驗證 $fields = explode('^', $key); foreach ($fields as $key) { $map[$key] = $data[$key]; } } elseif (strpos($key, '=')) { parse_str($key, $map); } else { $map[$key] = $data[$field]; } $pk = strval(isset($rule[3]) ? $rule[3] : $db->getPk()); if (isset($rule[2])) { $map[$pk] = ['neq', $rule[2]]; } elseif (isset($data[$pk])) { $map[$pk] = ['neq', $data[$pk]]; } if ($db->where($map)->field($pk)->find()) { return false; } return true; } ~~~ ### $validate->in() ~~~ protected function in($value, $rule) { return in_array($value, is_array($rule) ? $rule : explode(',', $rule)); } ~~~ ### $validate->notIn() ~~~ protected function notIn($value, $rule) { return !in_array($value, is_array($rule) ? $rule : explode(',', $rule)); } ~~~ ### $validate->between() ~~~ protected function between($value, $rule) { if (is_string($rule)) { $rule = explode(',', $rule); } list($min, $max) = $rule; return $value >= $min && $value <= $max; } ~~~ ### $validate->notbetween() ~~~ protected function notBetween($value, $rule) { if (is_string($rule)) { $rule = explode(',', $rule); } list($min, $max) = $rule; return $value < $min || $value > $max; } ~~~ ### $validate->length() ~~~ protected function length($value, $rule) { if (is_array($value)) { $length = count($value); } elseif ($value instanceof File) { $length = $value->getSize(); } else { $length = mb_strlen((string) $value); } if (strpos($rule, ',')) { // 長度區間 list($min, $max) = explode(',', $rule); return $length >= $min && $length <= $max; } else { // 指定長度 return $length == $rule; } } ~~~ ### $validate->min() ~~~ protected function min($value, $rule) { if (is_array($value)) { $length = count($value); } elseif ($value instanceof File) { $length = $value->getSize(); } else { $length = mb_strlen((string) $value); } return $length >= $rule; } ~~~ ### $validate->max() ~~~ protected function max($value, $rule) { if (is_array($value)) { $length = count($value); } elseif ($value instanceof File) { $length = $value->getSize(); } else { $length = mb_strlen((string) $value); } return $length <= $rule; } ~~~ ### $validate->before() ~~~ protected function before($value, $rule) { return strtotime($value) <= strtotime($rule); } ~~~ ### $validate->after() ~~~ protected function after($value, $rule) { return strtotime($value) >= strtotime($rule); } ~~~ ### $validate->expire() ~~~ protected function expire($value, $rule) { if (is_string($rule)) { $rule = explode(',', $rule); } list($start, $end) = $rule; if (!is_numeric($start)) { $start = strtotime($start); } if (!is_numeric($end)) { $end = strtotime($end); } return $_SERVER['REQUEST_TIME'] >= $start && $_SERVER['REQUEST_TIME'] <= $end; } ~~~ ### $validate->allowIp() ~~~ protected function allowIp($value, $rule) { return in_array($_SERVER['REMOTE_ADDR'], is_array($rule) ? $rule : explode(',', $rule)); } ~~~ ### $validate->denyIp() ~~~ protected function denyIp($value, $rule) { return !in_array($_SERVER['REMOTE_ADDR'], is_array($rule) ? $rule : explode(',', $rule)); } ~~~ ### $validate->regex() ~~~ protected function regex($value, $rule) { if (isset($this->regex[$rule])) { $rule = $this->regex[$rule]; } if (0 !== strpos($rule, '/') && !preg_match('/\/[imsU]{0,4}$/', $rule)) { // 不是正則表達式則兩端補上/ $rule = '/^' . $rule . '$/'; } return 1 === preg_match($rule, (string) $value); } ~~~ ### $validate->token() ~~~ protected function token($value, $rule, $data) { $rule = !empty($rule) ? $rule : '__token__'; if (!isset($data[$rule]) || !Session::has($rule)) { // 令牌數據無效 return false; } // 令牌驗證 if (isset($data[$rule]) && Session::get($rule) === $data[$rule]) { // 防止重復提交 Session::delete($rule); // 驗證完成銷毀session return true; } // 開啟TOKEN重置 Session::delete($rule); return false; } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看