php - cakephp 3 保存实体,尽管请求数据为空

标签 php cakephp cakephp-3.0

我正在用 cakephp 3 开发一个 REST api,我发现了一个奇怪的行为。

我更改了 routes.config,所以 .json, .xml 请求是可能的。我还在 Controller 初始化方法中加载了 RequestHandler 组件。

我在 UsersController() 中注册操作

public function register()
{
    $message = array('code' => '200', 'message' => 'The user could not be saved. Please, try again.');
    $user = $this->Users->newEntity($this->request->data);
    if ($this->request->is('post')) {
        if ($this->Users->save($user)) {
            $message = array('code' => '100', 'message' => 'The user has been registred');
        }
    }
    $this->set([
        'message' => $message,
        'user' => $user,
        '_serialize' => ['message', 'user']
    ]);
}

模型验证:

 public function validationDefault(Validator $validator)
    {
        $validator
            ->add('id', 'valid', ['rule' => 'numeric'])
            ->allowEmpty('id', 'create');

        $validator
            ->requirePresence('username', 'create');

        $validator
            ->notEmpty('username', 'A username is required')
            ->add('username', [
                'length' => [
                    'rule' => ['minLength', 3],
                    'message' => 'Username need to be at least 3 characters long',
                ]
            ])
            ->notEmpty('password', 'A password is required')
            ->add('password', [
                'length' => [
                    'rule' => ['minLength', 3],
                    'message' => 'Password need to be at least 3 characters long',
                ]
            ]);

        return $validator;
    }

问题: 如果我使用内容 header 发出发布请求 application/x-www-form-urlencoded 一切正常,将保存一个新用户并考虑验证规则。但是,如果我使用例如内容 header application/json 发出发布请求,则会保存一个空用户。原因是 $this->request->data 为空。但是为什么cakephp会保存空用户呢? (在数据库中用户名和密码被声明为非空)

最佳答案

传递null不会触发验证

newEntity() 的第一个参数是可选的,因此当传递 null 时,就像您根本没有传递任何东西一样,从而产生一个全新的,正在创建空实体,不会对其进行验证。

这就是为什么你不应该在那里做你正在做的事情的原因之一,你不应该将请求数据传递给 newEntity(),而是使用 patchEntity()在使用 newEntity() 创建的实体上,就像在 bake shell 生成的代码中完成的一样。

// ...
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
    $user = $this->Users->patchEntity($user, $this->request->data);
    if ($this->Users->save($user)) {
        // ...
    }
}
// ...

这样传递 null 将不会被接受,而是会导致错误,因为参数是必需的,并且必须是一个数组。

我想文档需要更新以反射(reflect)这一点。

使用额外的应用程序/表规则

除了在创建/更新实体时验证数据之外,还有应用程序/表规则,这些规则将在保存数据之前的任何情况下应用。使用这些规则,无论实体是如何创建的,您都可以防止此类有问题的保存操作。

这是一个非常基本的示例,用于测试字段是否为“空”:

public function buildRules(RulesChecker $rules)
{
    $rules->add(function ($entity, $options) {
        return !empty($entity->get('field'));
    });
    return $rules;
}

另见 Bookbook > ORM > Saving Data > Applying Application Rules

完全防止使用null

如果 null 是预期值,即在某些情况下它恰好为 null 是有效的,那么您甚至可能想要添加适当的预防措施并测试数据是否为 ​​null 在尝试使用它之前。

为什么插入记录时列显示 NOT NULL

好吧,这很容易解释,ORM 生成的 INSERT 查询将只包含实体的脏字段(已更改),并且默认情况下仅包含自动更新的字段通过 Timestamp 行为,因此插入一个空实体可能会导致类似的结果

INSERT INTO table (created, modified) VALUES ('2015-05-06 11:34:49', '2015-05-06 11:34:49')

根据您的 DBMS 和配置,这不会产生任何错误,例如,当不在严格模式下运行时,MySQL 会将未传递的列设置为其隐式默认值,因此您只会在实际值的情况下收到错误NULL 将为特定的 NOT NULL 列传递。

关于php - cakephp 3 保存实体,尽管请求数据为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30072649/

相关文章:

php - 三元运算符问题

php - 压缩显示的空间数字(类似于堆栈,但也适用于 <1)

php - 使用一个 SQL 查询的数据来获得另一个 SQL 查询的结果

php - 如何在 Cake 3 的表模型文件中设置数据源?

未找到 CakePHP 3.0 供应商类

php - 在命名空间之外导入类

php - 数据库查询不符合第二个条件

php - Cakephp 3 newEntity() 不工作

php - Cakephp 3.0 登录每次都返回 false

validation - CakePHP:为什么没有显示验证错误?