编程语言
首页 > 编程语言> > cakephp 3保存实体,尽管请求数据为空

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

作者:互联网

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

我更改了routes.config所以.json,.xml请求是可能的.我还在controllers initialize方法中加载了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;
    }

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

解决方法:

传递null不会触发验证

newEntity()的第一个参数是可选的,所以当传递null时,就像你没有传递任何东西一样,导致创建一个新的,新的空实体,不会被验证.

这就是你不应该做你在那里做的事情的原因之一,你不应该将请求数据传递给newEntity(),而是在使用newEntity()创建的实体上使用patchEntity(),就像它在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的方式将不被接受,并且因为参数是必需的而导致错误,并且必须是数组.

我想文档需要更新才能反映出来.

使用其他应用程序/表规则

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

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

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,cakephp-3-0
来源: https://codeday.me/bug/20190824/1710385.html