Skip to content

Commit 2729f93

Browse files
committed
改进
1 parent 614a78a commit 2729f93

File tree

1 file changed

+159
-13
lines changed

1 file changed

+159
-13
lines changed

src/Validate.php

Lines changed: 159 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// +----------------------------------------------------------------------
44
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
55
// +----------------------------------------------------------------------
6-
// | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
6+
// | Copyright (c) 2006~2025 http://thinkphp.cn All rights reserved.
77
// +----------------------------------------------------------------------
88
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
99
// +----------------------------------------------------------------------
@@ -241,6 +241,24 @@ class Validate
241241
*/
242242
protected $regex = [];
243243

244+
/**
245+
* Db对象
246+
* @var Db
247+
*/
248+
protected $db;
249+
250+
/**
251+
* 语言对象
252+
* @var Lang
253+
*/
254+
protected $lang;
255+
256+
/**
257+
* 请求对象
258+
* @var Request
259+
*/
260+
protected $request;
261+
244262
/**
245263
* @var Closure[]
246264
*/
@@ -270,6 +288,39 @@ public static function maker(Closure $maker)
270288
static::$maker[] = $maker;
271289
}
272290

291+
/**
292+
* 设置Lang对象
293+
* @access public
294+
* @param Lang $lang Lang对象
295+
* @return void
296+
*/
297+
public function setLang($lang)
298+
{
299+
$this->lang = $lang;
300+
}
301+
302+
/**
303+
* 设置Db对象
304+
* @access public
305+
* @param Db $db Db对象
306+
* @return void
307+
*/
308+
public function setDb($db)
309+
{
310+
$this->db = $db;
311+
}
312+
313+
/**
314+
* 设置Request对象
315+
* @access public
316+
* @param Request $request Request对象
317+
* @return void
318+
*/
319+
public function setRequest($request)
320+
{
321+
$this->request = $request;
322+
}
323+
273324
/**
274325
* 添加字段验证规则
275326
* @access protected
@@ -591,7 +642,7 @@ public function check(array $data, array | string $rules = []): bool
591642
$rules = $this->getGroupRules($rules);
592643
// 分组独立检测
593644
if ($rules instanceof Closure) {
594-
return $rules(new self)
645+
return $rules(new self())
595646
->alias($this->alias)
596647
->batch($this->batch)
597648
->failException($this->failException)
@@ -600,13 +651,13 @@ public function check(array $data, array | string $rules = []): bool
600651
}
601652

602653
if ($rules instanceof Validate) {
603-
$rules = $rules->getRules();
654+
$rules = $rules->getRules();
604655
}
605656

606657
if ($this->currentScene) {
607658
$this->getScene($this->currentScene);
608659
}
609-
660+
610661
foreach ($this->append as $key => $rule) {
611662
if (!isset($rules[$key])) {
612663
$rules[$key] = $rule;
@@ -647,8 +698,8 @@ public function check(array $data, array | string $rules = []): bool
647698
/**
648699
* 验证字段规则
649700
* @access protected
650-
* @param string $field 字段名
651-
* @param mixed $rule 验证规则
701+
* @param string $key 字段名
702+
* @param mixed $rule 验证规则
652703
* @param array $data 数据
653704
* @param string $title 字段描述
654705
* @return bool
@@ -664,7 +715,7 @@ protected function checkItems($key, $rule, $data, $title): bool
664715
$items = $rule->getRules();
665716
if ($items instanceof Closure) {
666717
// 获取验证集的规则
667-
$items = $items(new self)->getRule();
718+
$items = $items(new self())->getRule();
668719
}
669720
// 验证集的错误信息
670721
foreach ($rule->getMessage() as $name => $message) {
@@ -833,7 +884,7 @@ protected function checkItem(string $field, $value, $rules, $data, string $title
833884
continue;
834885
}
835886

836-
if ('must' == $type || str_starts_with($type, 'require') || in_array($type, $this->must) || (!is_null($value) && '' !== $value)) {
887+
if ('must' == $type || str_starts_with($type, 'require') || in_array($field, $this->must) || (!is_null($value) && '' !== $value)) {
837888
$result = call_user_func_array($callback, [$value, $rule, $data, $field, $title]);
838889
} else {
839890
$result = true;
@@ -844,6 +895,9 @@ protected function checkItem(string $field, $value, $rules, $data, string $title
844895
// 验证失败 返回错误信息
845896
if (!empty($msg[$i])) {
846897
$message = $msg[$i];
898+
if (is_string($message) && str_starts_with($message, '{%')) {
899+
$message = $this->lang->get(substr($message, 2, -1));
900+
}
847901
} else {
848902
$message = $this->getRuleMsg($field, $title, $type, $rule);
849903
}
@@ -1092,6 +1146,23 @@ protected function getImageType($image)
10921146
}
10931147
}
10941148

1149+
/**
1150+
* 验证表单令牌
1151+
* @access public
1152+
* @param mixed $value 字段值
1153+
* @param mixed $rule 验证规则
1154+
* @param array $data 数据
1155+
* @return bool
1156+
*/
1157+
public function token($value, string $rule, array $data): bool
1158+
{
1159+
if ($this->request) {
1160+
$rule = !empty($rule) ? $rule : '__token__';
1161+
return $this->request->checkToken($rule, $data);
1162+
}
1163+
return true;
1164+
}
1165+
10951166
/**
10961167
* 验证是否为合格的域名或者IP 支持A,MX,NS,SOA,PTR,CNAME,AAAA,A6, SRV,NAPTR,TXT 或者 ANY类型
10971168
* @access public
@@ -1321,9 +1392,76 @@ public function image($file, $rule): bool
13211392
public function dateFormat($value, $rule): bool
13221393
{
13231394
$info = date_parse_from_format($rule, $value);
1395+
if (strlen((string) $info['year']) != 4 && strpos($rule, 'Y') !== false) {
1396+
return false;
1397+
}
13241398
return 0 == $info['warning_count'] && 0 == $info['error_count'];
13251399
}
13261400

1401+
/**
1402+
* 验证是否唯一
1403+
* @access public
1404+
* @param mixed $value 字段值
1405+
* @param mixed $rule 验证规则 格式:数据表,字段名,排除ID,主键名
1406+
* @param array $data 数据
1407+
* @param string $field 验证字段名
1408+
* @return bool
1409+
*/
1410+
public function unique($value, $rule, array $data = [], string $field = ''): bool
1411+
{
1412+
if (!$this->db) {
1413+
return true;
1414+
}
1415+
1416+
if (is_string($rule)) {
1417+
$rule = explode(',', $rule);
1418+
}
1419+
1420+
if (str_contains($rule[0], '\\')) {
1421+
// 指定模型类
1422+
$db = new $rule[0]();
1423+
} else {
1424+
$db = $this->db->name($rule[0]);
1425+
}
1426+
1427+
$key = $rule[1] ?? $field;
1428+
$map = [];
1429+
1430+
if (str_contains($key, '^')) {
1431+
// 支持多个字段验证
1432+
$fields = explode('^', $key);
1433+
foreach ($fields as $key) {
1434+
if (isset($data[$key])) {
1435+
$map[] = [$key, '=', $data[$key]];
1436+
}
1437+
}
1438+
} elseif (strpos($key, '=')) {
1439+
// 支持复杂验证
1440+
parse_str($key, $array);
1441+
foreach ($array as $k => $val) {
1442+
$map[] = [$k, '=', $data[$k] ?? $val];
1443+
}
1444+
} elseif (isset($data[$field])) {
1445+
$map[] = [$key, '=', $data[$field]];
1446+
}
1447+
1448+
$pk = !empty($rule[3]) ? $rule[3] : $db->getPk();
1449+
1450+
if (is_string($pk)) {
1451+
if (isset($rule[2])) {
1452+
$map[] = [$pk, '<>', $rule[2]];
1453+
} elseif (isset($data[$pk])) {
1454+
$map[] = [$pk, '<>', $data[$pk]];
1455+
}
1456+
}
1457+
1458+
if ($db->where($map)->field($pk)->find()) {
1459+
return false;
1460+
}
1461+
1462+
return true;
1463+
}
1464+
13271465
/**
13281466
* 使用filter_var方式验证
13291467
* @access public
@@ -1760,7 +1898,7 @@ public function regex($value, $rule): bool
17601898
* 获取内置正则验证规则
17611899
* @access public
17621900
* @param string $rule 验证规则 正则规则或者预定义正则名
1763-
* @return bool
1901+
* @return string
17641902
*/
17651903
protected function getDefaultRegexRule(string $rule): string
17661904
{
@@ -1878,7 +2016,7 @@ protected function getRuleMsg(string $attribute, string $title, string $type, $r
18782016
} elseif (str_starts_with($type, 'require')) {
18792017
$msg = $this->typeMsg['require'];
18802018
} else {
1881-
$msg = $title . '规则不符';
2019+
$msg = $title . ($this->lang ? $this->lang->get('not conform to the rules') : '规则不符');
18822020
}
18832021

18842022
if (is_array($msg)) {
@@ -1898,6 +2036,14 @@ protected function getRuleMsg(string $attribute, string $title, string $type, $r
18982036
*/
18992037
protected function parseErrorMsg(string $msg, $rule, string $title)
19002038
{
2039+
if ($this->lang) {
2040+
if (str_starts_with($msg, '{%')) {
2041+
$msg = $this->lang->get(substr($msg, 2, -1));
2042+
} elseif ($this->lang->has($msg)) {
2043+
$msg = $this->lang->get($msg);
2044+
}
2045+
}
2046+
19012047
if (is_array($msg)) {
19022048
return $this->errorMsgIsArray($msg, $rule, $title);
19032049
}
@@ -1974,10 +2120,10 @@ protected function getGroupRules(string $group)
19742120
{
19752121
$method = 'rules' . Str::studly($group);
19762122
if (method_exists($this, $method)) {
1977-
$validate = call_user_func_array([$this, $method], [new self]);
2123+
$validate = call_user_func_array([$this, $method], [new self()]);
19782124
return $validate->alias($this->alias)
1979-
->batch($this->batch)
1980-
->failException($this->failException);
2125+
->batch($this->batch)
2126+
->failException($this->failException);
19812127
}
19822128
return $this->group[$group] ?? [];
19832129
}

0 commit comments

Comments
 (0)