【问题标题】:How can I convert validation error field names to input names in CakePHP?如何将验证错误字段名称转换为 CakePHP 中的输入名称?
【发布时间】:2012-09-13 20:06:15
【问题描述】:

我有一个带有表单和验证的 CakePHP(最新版本)网络应用程序,所有这些都使用传统的回发正常工作,但现在我正在切换一些表单以通过 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"]
}}

请注意,错误键中只有基本的数据库表字段名称。它们不会转换为 Data[User][username] 格式,FormHelper 通常会处理这些格式。 p>

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

【问题讨论】:

    标签: cakephp


    【解决方案1】:

    这是因为 $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"
      ]
    }
    

    【讨论】:

    • 感谢您的回答。循环有效,但有没有一种方法可以通用地完成所有模型,而不是硬编码“用户”?我想把它放在 AppController.php 中,这样任何模型都可以将validationErrors 传递给它并获取重新格式化的数组。您提到在$this->validationErrors 上循环,但我认为不存在这样的对象。即使$this->User->validationErrors 不为空,它对我来说也是空的。
    • $this->validationErrors 仅在视图中可用,因此您必须从那里进行操作。无论如何,您不应该直接从控制器回显 json,这是不好的做法。我用如何循环错误并输出你想要的方式更新了答案。您可以考虑将代码放在帮助程序中以保持 DRY。
    • 我能够采用您建议的视图代码并将其放在共享视图中。现在,当我想从基于任何模型或模型组合的任何控制器以 JSON 形式返回验证错误时,我只需在控制器中验证(或尝试保存)然后执行 $this->layout = 'ajax'; $this->viewPath = 'shared'; $this->view = 'json_validation'; 然后退出。这回答了我的问题。谢谢!
    【解决方案2】:
    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);
                }
    

    【讨论】:

      【解决方案3】:
      $response['errors']['User'] = $this->User->validationErrors;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-29
        • 1970-01-01
        • 2017-01-16
        • 2016-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-21
        相关资源
        最近更新 更多