Symfony2 細節小計4

驗證約束

打開註解約束的配置:
# app/config/config.yml
framework:
    validation: { enable_annotations: true }
控制器中校驗實體:
$validator = $this->get('validator');
$errors = $validator->validate(實體對象); //檢驗失敗則返回錯誤列表對象
---count($errors) AND ($errorsString = (string) $errors); 
|
---{% for error in errors %} {{error.message}} {% endfor %}  #每一個錯誤表明了一個 ConstraintViolation

表單驗證:
$form = $this->createForm(new 表單類(), 空實體對象);
$form->handleRequest($request); 
if ($form->isValid()) {
  return $this->redirectToRoute(...);
} 
return $this->render('author/form.html.twig', array(
   'form' => $form->createView(),
));
 
 直接調用驗證函數:
 $emailConstraint = new Assert\Email();
 $emailConstraint->message = 'Invalid email address';
 $errorList = $this->get('validator')->validate(
        $email,
        $emailConstraint
    );
use Symfony\Component\Validator\Constraints as Assert;
能夠約束的對象: 屬性約束、 Getters公共方法(get,is,has開頭的方法)、 類約束(可用callback等來約束整個類)


驗證組,將實體的校驗規則分不一樣組,校驗時激活驗證指定組的規則:default組、 類名組。
例子,registration組:
$errors = $validator->validate($author, null, array('registration')); //經過驗證組來驗證, 沒有指定約束,則使用default組來驗證

設定驗證組驗證順序:
 * @Assert\GroupSequence({"User", "Strict"}) //在類頭部有序註解出驗證組
 
 驗證組序列provider(指定那些驗證組激活)
 * @Assert\GroupSequenceProvider  //在類頭部註解使用驗證組provider
 集成接口: implements GroupSequenceProviderInterface
 實現方法: getGroupSequence
 返回 激活的驗證組名字的數組


表單

表單對象的設計意圖:
映射請求數據到實體對象 或 映射實體對象到表單字段輸出
更方便的對請求數據校驗實體類的驗證規則
實現代碼複用, 將表單收編到本身的可用組件庫中

## 最佳實踐的建議 ##
# 推薦在模板中編寫表單按鈕
# 在表單類或者控制器中添加輸入域
# 通常不要把表單註冊爲服務
建立表單類 -> 實例化表單對象 -> 表單處理提交併驗證 -> 返回空表單或跳轉 -> 模板繪製表單

## 建立表單 ##
//////自定義類建立表單/////////
namespace xxBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class MyType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title')
            ->add('summary', 'textarea')
            ->add('authorEmail', 'email')
            ->add('publishedAt', 'datetime')
            ->add('save','submit',array('label'=>'yes')); #不推薦表單類中添加按鈕,應在模板中
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'xxBundle\Entity\My',
            'validation_groups' => array('registration'), # 指定表單校驗時, 使用實體的哪一個校驗組
                                                          # 'validation_groups'=>false 關閉校驗,但還會執行些基礎檢查
                                   # array('AppBundle\Entity\Client','determineValidGp')經過client類的一個回調方法來決定驗證組
                                   # 回調方法接收參數 FormInterface $form
        ));
    }

    public function getName()
    {
        return 'My';
    }
}
//////或者 控制器中建立表單//////////
use AppBundle\Entity\Post; #實體類
public function xxAction(Request $request)
{
   $form = $this->createFormBuilder(new Post()【, $options】)
		        【->setAction($this->generateUrl('target_route'))】
		        【->setMethod('GET')】
		        ->add('name')  #忽略add第二參數或爲null, 則自動推斷類型
		        ->add('file')
		        ->getForm();
}
// $options = array(
    'validation_groups' => array('registration'), //指定表單校驗時, 使用實體的哪一個校驗組
)
##################################################################


## 實例化表單 ##
use AppBundle\Entity\Post; #實體類
use xxBundle\Form\MyType; #表單類
public function xxAction(Request $request)
{
    $post = new Post();
    $post->setTitle('this is title');
    $form = $this->createForm(new MyType(), $post【, array(
        'action' => $this->generateUrl('target_route'),
        'method' => 'GET',
    )】);
    ...
}
##################################################################


## 表單提交 處理驗證 ##
# isValid驗證會先內部調用isSubmitted,但爲了語義明顯,仍是推薦顯示調用下isSubmitted
use AppBundle\Entity\Post; #實體類
use xxBundle\Form\MyType; #表單類
public function xxAction(Request $request) {
	$post = new Post();
	$form = $this->createForm(new MyType(), $post);
	$form->handleRequest($request); //處理post提交請求,驗證數據並寫入實體對象,驗證失敗則將顯示報錯信息。
                                        //get請求也能識別。
	if ($form->isSubmitted() && $form->isValid()) { //表單驗證
		$em = $this->getDoctrine()->getManager();
		$em->persist($post); //或者 $em->persist($form->getData());
		$em->flush();
        	
		return $this->redirect($this->generateUrl(
		    'post_show',
		    array('id' => $post->getId())
		));
	} else { //渲染空表單
		return $this->render('form.html.twig', array(
		   'form' => $form->createView(),
		));
	}
}
##################################################################


## 模板繪製表單 ##
/////////單行代碼粗放繪製///////////
{{ form_start(form【, {'attr': {'class': 'blog-form'}}】) }}
    {{ form_widget(form) }} <!-- 全部字段和表單報錯 -->
    <input type="submit" value="yes" class="btn" />
{{ form_end(form) }} <!-- CSRF Token及一些其餘隱藏字段 -->
///////或者 表單控件行繪製////////
{{ form_start(form【, {'action': path('target_route'), 'method': 'GET'}】) }}
    {{ form_errors(form) }} <!-- 表單的報錯 -->
    {{ form_row(form.title) }} <!-- title字段及其報錯 -->
    {{ form.vars.value.title }} <!-- 輸出當前的title模板變量 -->
{{ form_end(form) }}
///////或者更細緻的 表單字段繪製////////
{{ form_start(form) }}
    {{ form_errors(form) }} <!-- 表單的報錯 -->

    <div> <!-- 這裏的一個div至關於form_row -->
        {{ form_label(form.dueDate【, '2015-10'】) }}  <!-- 可臨時替換標籤文本 -->
        {{ form_errors(form.dueDate) }}
        {{ form_widget(form.dueDate【,{'attr': {'class': 'dateclass'}}】) }}
        {{ form.dueDate.vars.id }} <!-- 輸出字段的某屬性 -->
    </div>
    {{ form_widget(form.save) }}
{{ form_end(form) }}
##################################################################
## 控制器中讀寫表單字段 ##
$form->get('dueDate')->getData();
$form->get('dueDate')->setData(new \DateTime());

## 檢測表單按鈕點擊 ##
$form->get('save')->isClicked(); //檢測save按鈕是否被點擊

## 臨時關閉客戶端的required等校驗功能 ##
{{ form(form, {'attr': {'novalidate': 'novalidate'}}) }}
或
submit按鈕添加屬性 'attr' => array('novalidate' => 'novalidate'),

## 表單字段配置 ##
$builder->add('名字', '類型', array(
'label'    =>    'yes',  #標籤文字,false則不顯示
'attr'     =>    array('class'=>'btn'),
'validation_groups' => false, # 適用於submit按鈕
'required  =>    true, #前端html5實現字段必填
'mapped'   =>    false, #該字段不映射到實體, 好比是否贊成勾選框,沒有此設置,則拋異常:字段不存在於實體 
))
表單字段類型: 
文字類:text、textarea、email、integer、number、password、url
選擇類:choice(下拉)
時間類:date、datetime、time
其餘類:checkbox、radio、file
組框:collection
隱藏域:hidden
按鈕類:button、reset、submit
相關文章
相關標籤/搜索