2013-08-07 53 views
3

Symfony(v 2.3.2)表單有一個奇怪的問題。這是非常簡單的形式,沒有關係。我還應該注意到,這種形式僅用於REST API。Symfony2表單提交無效的布爾值

所以我有一個發佈的領域(布爾)。在實體上它默認設置爲false。

更新時,REST API客戶端發送正確的PUT請求,即...&[entity]published=0&...。這個值也在Symfony分析器中的表單參數中顯示。

但是我注意到數據庫中的實際值設置爲true(或1,因爲它是tinyint)。 Request: 0, form: 1

所以,要找出什麼問題,我$form->submit($request);

throw new \Exception(sprintf('Request: %s, form: %s', $request->get('entity')['published'], $form->get('published')->getData()));

throw new \Exception(sprintf('Request: %s, form: %s', $request->get('entity')['published'], $form->getData()->getPublished()));

異常消息稱後添加throw語句。這意味着,在某處提交方法的字符串值「0」轉換爲1

場構造與$builder->add('published', 'checkbox', [ 'required' => false ])

而且我發現奇怪的東西,這可能是相關的。在Symfony分析器,面板請求中,我收到錯誤:Warning: json_encode(): Invalid UTF-8 sequence in classes.php line 3758,我沒有發送任何奇怪的字符 - 只是單詞「測試」。

回答

2

進一步的調查顯示,典型的HTML表單複選框僅在檢查時才發送到服務器。所以我認爲將發送值設置爲0 | false | off會使其工作,就好像它將被設置爲true。

因此,如果您將表單窗口小部件設置爲鍵入複選框,則不要在請求中發送複選框,如果您希望將其設置爲false。在我的情況是這樣的:

Array 
(
    [entity] => Array 
    (
     [id] => 73 
     [_token] => d63dad39ea458f7d3c7ae5dbea10c325cb9ee93d 
    ) 
) 

否則發送任何東西,0,假,過會工作太

Array 
(
    [entity] => Array 
    (
     [id] => 73 
     [published] => 1|0|false|on|off 
     [_token] => d63dad39ea458f7d3c7ae5dbea10c325cb9ee93d 
    ) 
) 
0

使用時把這個正好是有點問題...... 我解決它通過添加用戶到我的所有形式的解決這個問題(此代碼也解決在使用PUT的問題沒有填寫的所有資料):

class RestFormSubscriber implements EventSubscriberInterface { 

    /** 
    * {@inheritdoc} 
    */ 
    public static function getSubscribedEvents() 
    { 
     return array(FormEvents::PRE_SUBMIT => "preSubmit"); 
    } 

    /** 
    * Remove null fields on update 
    * Fixes boolean value 
    * @param FormEvent $event 
    */ 
    public function preSubmit(FormEvent $event) 
    { 
     $form = $event->getForm(); 
     $data = $event->getData(); 

     $isPUT = strtoupper($form->getConfig()->getMethod()) == "PUT"; 

     $accessor = PropertyAccess::createPropertyAccessor(); 
     foreach ($form->all() as $name => $child) { 
      if ($isPUT && !isset($data[$name])) { 
       $form->remove($name); 
       continue; 
      } 
      if(is_bool($accessor->getValue($form->getData(), $name))) { 
       $val = $data[$name]; 
       $data[$name] = ($val=="true")||($val=="1")||($val=="on"); 
      } 
     } 
     $event->setData($data); 
    } 
}