2015-03-25 40 views
0

我收到從Zend的形式的Zend Framework2形式錯誤陣列要JSON

Array 
(
    [user] => Array 
     (
      [firstName] => Array 
       (
        [isEmpty] => Please enter First Name 
       ) 

      [lastName] => Array 
       (
        [isEmpty] => Please enter Last Name 
       ) 

      [password] => Array 
       (
        [isEmpty] => Please enter Password 
       ) 

      [confirmPassword] => Array 
       (
        [isEmpty] => Please enter Confirm Password 
       ) 

      [email] => Array 
       (
        [isEmpty] => Please enter Email Address 
       ) 

      [gender] => Array 
       (
        [notInArray] => Gender must be Male OR Female 
        [isEmpty] => Please select your gender 
       ) 

      [phone] => Array 
       (
        [isEmpty] => Value is required and can't be empty 
       ) 

      [birthDate] => Array 
       (
        [isEmpty] => Please enter Birth Date 
       ) 

      [country] => Array 
       (
        [id] => Array 
         (
          [isEmpty] => Please select Country 
         ) 

       ) 

      [userGroup] => Array 
       (
        [id] => Array 
         (
          [isEmpty] => Please select User Group 
         ) 

       ) 

     ) 

) 

此陣列,我想這個陣列被轉換爲下面的數組:

Array 
(
    [user[firstName]] => [{"Please enter First Name"}] 
    [user[lastName]] => [{"Please enter Last Name"}] 

    ........... 

    [user[gender]] => [{"Gender must be Male OR Female","Please select your gender"}] 

    .............. 
    [user[country][id]] => [{"Please select Country"}] 
) 

我嘗試以下代碼但它沒有工作

$errors = $form->getMessages(); 
       $newErrors = array(); 
       foreach ($errors as $key => $value) { 
        $elementName = $key; 
        if(is_array($value)) { 
         foreach ($value as $k => $v) { 
          $elementName .= $k; 
          if(!is_array($v)) { 
           $message = $v; 
           $newErrors[$elementName] = json_encode($v); 
          } else { 
           foreach ($v as $ke => $va) { 
            $elementName .= $ke; 
            if(!is_array($va)) { 
             $newErrors[$elementName] = json_encode($va); 
            } 
           } 
          } 
         } 
        } 
       } 

但它沒有奏效。

+0

您可能想詳細說明您的用例,爲什麼您需要JSON中的錯誤?您是否通過AJAX發佈表單,並希望在表單上應用一些錯誤樣式? – AlexP 2015-03-25 12:31:32

+0

絕對是的,我用ajax驗證表單並需要json響應。 – 2015-03-25 12:33:06

回答

0

直接回答你的問題。

這還沒有經過測試,雖然我相信它應該工作。

public function formatElementErrors(FieldsetInterface $collection, array $data, $parent = null) 
{ 
    $results = []; 

    foreach($data as $name => $errors) { 

     if (! $collection->has($name) || ! is_array($errors)) { 
      continue; 
     } 

     $element = $collection->get($name); 

     $name = isset($parent) ? sprintf('%s[%s]', $parent, $name) : $name; 

     if ($element instanceof FieldsetInterface) { 

      $results = array_merge(
       $results, 
       $this->formatElementErrors($element, $errors, $name) 
      ); 

     } else { 
      if (! isset($results[$name])) $results[$name] = []; 

      foreach($errors as $message) { 
       $results[$name][] = $message; 
      } 
     } 
    } 
    return $results; 
} 

$errors = $this->formatElementErrors($form, $errors); 
+0

你幾乎在那裏,但它是給[country [id]]而不是用戶[country [id]] ..我們可以修復它嗎? – 2015-03-25 13:58:17

+0

我認爲應該解決它,當我有機會時,我會嘗試並測試它。 – AlexP 2015-03-25 14:01:30

+0

非常感謝AlexP。你真的很棒....... – 2015-03-25 14:03:25

0

儘管有可能,而不是檢索帶有表單錯誤的JSON數組,我選擇返回整個表單的HTML預渲染(包括錯誤樣式等)。

我可以看到,您嘗試重新鍵入結果數組是因爲表單元素在嵌套時被賦予新名稱;這意味着你需要一些麻煩的JS代碼來搜索DOM中的這些元素並添加相關的樣式。

用我的解決方案,我們使用標準視圖渲染(意味着普通的ZF2視圖助手)來應用錯誤。

例如

// We are creating something 
public function createAction() 
{ 
    $serviceManager = $this->getServiceLocator(); 
    $formElementManager = $serviceManager->get('FormElementManager'); 

    $form = $this->formElementManager->get('MyModule\Form\SomeCreateForm'); 

    $request = $this->getRequest(); 

    $view = new ViewModel(compact('form')); 

    if ($request->isPost()) { 

     $form->setData($request->getPost()); 

     if ($form->isValid()) { 

      // handle form success 

     } else if ($request->isXmlHttpRequest()) { 

      // The form data was posted via ajax and is invalid 

      // Set the view template to a view that just renders the form 
      // 
      // For example, the script would include: 
      // 
      // <?php echo $this->form($form); 
      // 
      $view->setTempalte('my/view-template/form'); 

      // Now render the view, using the view renderer 
      $content = $serviceManager->get('ViewRenderer')->renderer($view); 

      return new JsonModel([ 
       'success' => false, // flag for us to know we have an error in JS 
       'content' => $content // The HTML content of the form, including the errors 
      ]); 
     } 
    } 

    $view->setTempalte('my/view-template/create'); 

    return $view; 
} 

爲了擴大這一點,你也可以創建一個控制器插件「JsonModel」封裝此。如果你在一個Zend\View\Model\ViewModel傳爲「內容」鍵的插件會再處理它

渲染控制器代碼,然後將成爲分配清潔

return $this->jsonModel([ 
    'content' => $view 
]); 
+0

我不想要這樣,因爲我只是想按照我的要求獲得json錯誤響應,因爲HTML對於ajax響應來說太重了。 – 2015-03-25 12:55:18

+0

我可以很容易地在jQuery中獲得用戶[firstName]或用戶[country] [id]輸入字段,並可以通過javascript設置錯誤消息。 – 2015-03-25 12:56:26

+0

我還沒有看到使用這種方法的任何性能問題;儘管迴應會更大,因此會更慢;在現實世界中,差異可以忽略不計(它只是文字)。這個決定當然將完全取決於你的要求和偏好。就個人而言,我總是會選擇更乾淨的代碼解決方案,因爲它有助於維護性。 – AlexP 2015-03-25 13:07:02

0

下面的代碼轉換陣列需要的格式。但首先你想作爲輸出是混合json & php數組,不應該這樣做。相反,轉換成一個php數組然後做json編碼。

$data = array(); 
foreach($arr['user'] as $key => $item) 
{ 
    foreach($item as $key1 => $item1) 
    { 
     if(is_array($item1)) 
     { 
      list($key2, $item2) = each($item1); 
      $data['user'][$key][$key1] = $item2; 
     } 
     else 
     { 
      $data['user'][$key] = $item1; 
     }     
    }    
} 
print_r($data); 
echo json_encode($data); 

陣列輸出是

Array 
(
    [user] => Array 
     (
      [firstName] => Please enter First Name 
      [lastName] => Please enter Last Name 
      [password] => Please enter Password 
      [confirmPassword] => Please enter Confirm Password 
      [email] => Please enter Email Address 
      [gender] => Please select your gender 
      [phone] => Value is required and can't be empty 
      [birthDate] => Please enter Birth Date 
      [country] => Array 
       (
        [id] => Please select Country 
       ) 

      [userGroup] => Array 
       (
        [id] => Please select User Group 
       ) 

     ) 

) 

同時施加json_encodereturn以下JSON字符串。

{ 
    "user": { 
    "firstName": "Please enter First Name", 
    "lastName": "Please enter Last Name", 
    "password": "Please enter Password", 
    "confirmPassword": "Please enter Confirm Password", 
    "email": "Please enter Email Address", 
    "gender": "Please select your gender", 
    "phone": "Value is required and can't be empty", 
    "birthDate": "Please enter Birth Date", 
    "country": { 
     "id": "Please select Country" 
    }, 
    "userGroup": { 
     "id": "Please select User Group" 
    } 
    } 
} 
+0

你見過嗎,我想要的是什麼? – 2015-03-25 13:33:46

+0

是的,我已經添加到頂部了。這與你想要的完全不一樣。但可能是一個更好的方式發送JSON到PHP的JavaScript。 – 2015-03-25 13:39:52