2

我有一个带有表单和验证的 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"]
}}

错误数组的键需要与表单字段上的名称属性相对应。我们有一些预构建的客户端脚本,期望以这种方式格式化 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 通常会处理的 data[User][username] 格式。

在我返回之前有一些简单的方法来调整数组吗?我不想简单地循环并预先添加“data [User]”,因为这不够健壮。我想要一些可以放在一个地方并从各种控制器调用各种模型的代码。FormHelper 使用什么来提供输入名称属性?我可以利用它吗?我应该以某种方式使用 JSON 视图吗?

4

3 回答 3

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"
  ]
}
于 2012-09-13T20:58:20.383 回答
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);
            }
于 2016-09-28T06:54:59.857 回答
0
$response['errors']['User'] = $this->User->validationErrors;
于 2013-09-27T08:29:25.753 回答