q0r*_*0re 3 php cakephp cakephp-3.0
我正在使用cakephp 3开发REST api,我发现了一个奇怪的行为.
我更改了routes.config,因此可以.json, .xml请求.我还在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']
]);
}
Run Code Online (Sandbox Code Playgroud)
模型验证:
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;
}
Run Code Online (Sandbox Code Playgroud)
问题:
如果我发布带有内容标题的帖子请求application/x-www-form-urlencoded一切正常,则会保存新用户并考虑验证规则.但是,如果我使用例如内容标题发布帖子请求,application/json则保存空用户.原因$this->request->data是null.但为什么cakephp会保存空用户?(在数据库中,用户名和密码声明为非null)
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)) {
// ...
}
}
// ...
Run Code Online (Sandbox Code Playgroud)
这种方式传递null将不被接受,并导致错误,因为参数是必需的,并且必须是数组.
我想文档需要更新才能反映出来.
除了在创建/更新实体时验证数据,还有应用程序/表规则,在保存数据之前将在任何情况下应用.使用这些规则,无论实体如何创建,您都可以防止出现这种有问题的保存操作.
这是一个非常基本的例子,用于测试字段是否为"空":
public function buildRules(RulesChecker $rules)
{
$rules->add(function ($entity, $options) {
return !empty($entity->get('field'));
});
return $rules;
}
Run Code Online (Sandbox Code Playgroud)
另请参见Bookbook> ORM>保存数据>应用应用程序规则
null被使用如果null是期望值,即在某些情况下它恰好为空有效,那么您甚至可能希望null在尝试使用它之前添加适当的预防措施并测试数据.
NOT NULL?嗯,这很容易解释,INSERTORM生成的查询将只包含脏(更改)实体的字段,默认情况下只是由Timestamp行为自动更新的字段,因此插入一个空实体可能会产生类似的结果
INSERT INTO table (created, modified) VALUES ('2015-05-06 11:34:49', '2015-05-06 11:34:49')
Run Code Online (Sandbox Code Playgroud)
根据您的DBMS和配置,这不会产生任何错误,例如,MySQL不会在严格模式下运行时将未传递的列设置为其隐式默认值,因此您只会在实际值NULL传递时收到错误对于特定NOT NULL列.