我有一个CakePHP(最新版本)Web应用程序,表单和验证都使用传统的回发正常工作,但现在我正在切换一些表单通过ajax提交。当存在验证错误时,我希望将它们作为JSON格式返回客户端,如下所示:
{
"success":false,
"errors":{
"data[User][username]":["This is not a valid e-mail address"],
"data[User][password]":["You must choose a password"]
}}
errors数组的键需要与表单字段上的name属性相对应。我们有一些预建的客户端脚本,期望以这种方式格式化JSON。好消息是,这与CakePHP中的validationErrors对象非常接近。所以我现在正在我的控制器中执行此操作:
if ($this->User->save($this->request->data)) {
} else {
if ($this->request->is('ajax')) {
$this->autoRender = $this->layout = false;
$response['success'] = false;
$response['errors'] = $this->User->validationErrors;
echo json_encode($response);
exit(0);
}
}
但是,这就是JSON响应的样子:
{
"success":false,
"errors":{
"username":["This is not a valid e-mail address"],
"password":["You must choose a password"]
}}
请注意,错误键中只包含基本数据库表字段名称。它们不会转换为数据[用户] [用户名]格式,FormHelper通常会处理这些格式。
在返回数组之前是否有一些简单的方法来调整数组?我不想简单地循环并添加“数据[用户]”,因为它不够健壮。我想要一些代码,我可以放在一个地方,并从各种控制器调用各种型号。 FormHelper使用什么来提出输入名称属性?我能点进去吗?我应该以某种方式使用JSON视图吗?
答案 0 :(得分:2)
那是因为这就是$validationErrors
数组的格式化方式。要获得你想要的输出,你必须循环,没有办法解决它。
foreach ($this->User->validationErrors as $field => $error) {
$this->User->validationErrors["data[User][$field]"] = $error;
unset($this->User->validationErrors[$field]);
}
我建议将所有错误传递给json_encode()
。 $this->validationErrors
是视图上可用的所有模型验证错误的组合列表(在渲染后编译)。您应该将显示逻辑(回显json)移动到视图中,然后在那里循环显示。
$errors = array();
foreach ($this->validationErrors as $model => $modelErrors) {
foreach ($modelErrors as $field => $error) {
$errors["data[$model][$field]"] = $error;
}
}
$response['errors'] = $errors;
echo json_encode($response);
这将输出如下内容:
{
"success":false,
"errors": [
"data[User][username]": "This is not a valid e-mail address",
"data[User][password]": "This is not a valid password",
"data[Profile][name]": "Please fill in the field"
]
}
答案 1 :(得分:1)
I have created a small recursive function to create validation error as a string with column name so that can be passed as json object.
/**
* prepare erorr message to be displayed from js
*
* @param array $errors validation error array
* @param stringn $message refernce variable
*
* @return void
*/
public function parseValidationErrors($errors, &$message)
{
foreach ($errors as $columnName => $error) {
$message .= "<strong>$columnName:</strong> ";
foreach ($error as $i => $msg) {
if (is_array($msg)) {
$this->_parseValidationErrors($msg, $message);
} else {
$message .= str_replace("This field", "", $msg . " ");
isset($error[$i + 1]) ? $message .= " and " : $message;
}
}
}
}
和控制器代码就是这样。
if (!$this->YourModel->saveAll($modelObject)) {
$errors = $this->YourModel->validationErrors;
$message = '';
$this->parseValidationErrors($errors, $message);
$response = array('status' => 'error', 'message' => $message);
}
答案 2 :(得分:0)
$response['errors']['User'] = $this->User->validationErrors;