Jay*_*mon 5 php validation cakephp cakephp-3.0
我的BlockedTable.php中有以下规则
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(['date', 'time']),
['message' => 'unique error']);
return $rules;
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,这已经运行良好 - 如果我尝试使用已有的日期和时间保存新记录,它会阻止我保存.
但是,如果我的时间是NULL,如下面的条目;
?????????????????????????????
? ID ? Date ? Time ?
?????????????????????????????
? 1 ? 22/08/1985 ? NULL ?
?????????????????????????????
Run Code Online (Sandbox Code Playgroud)
该规则仍允许我使用相同的数据保存新条目.因此,如果我尝试保存$date = 22/08/1985并$time = NULL保存正常,并且我的数据库中存在重复记录.由于上述规则,我原本预计会失败吗?
为什么会这样?如何防止重复输入NULL值?
在此先感谢您的帮助.
NULL与使用普通比较运算符进行比较,即column = NULL(唯一规则所做的),应该始终是NULL(AFAIK 至少在 MySQL 和 Postgres 中是这种情况),因此什么也找不到,因此只要存在NULL涉及的价值。
如果您想防止这种行为,则必须使用自定义规则,因为内置规则根本不支持它。我认为这是值得改进的地方,因此您可能需要在 GitHub 上开票。
这是覆盖规则类的基本示例IsUnique,它基本上只是IS向条件键添加一个运算符,以便NULL检查最终为column IS NULL.
public function __invoke(EntityInterface $entity, array $options)
{
if (!$entity->extract($this->_fields, true)) {
return true;
}
$alias = $options['repository']->alias();
$conditions = $this->_alias($alias, $entity->extract($this->_fields));
if ($entity->isNew() === false) {
$keys = (array)$options['repository']->primaryKey();
$keys = $this->_alias($alias, $entity->extract($keys));
if (array_filter($keys, 'strlen')) {
$conditions['NOT'] = $keys;
}
}
// handle null values
foreach ($conditions as $key => $value) {
if ($value === null) {
$conditions[$key . ' IS'] = $value;
unset($conditions[$key]);
}
}
return !$options['repository']->exists($conditions);
}
Run Code Online (Sandbox Code Playgroud)
理论上,您也可以在重写IsUnique::_alias()方法中执行此操作,该方法无需重新实现原始规则类中的代码即可工作,但这并不是真正正确的位置。
https://github.com/cakephp/cakephp/blob/3.2.5/src/ORM/Rule/IsUnique.php
也可以看看