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 关闭校验
        ));
    }

    public function getName()
    {
        return ‘My‘;
    }
}
//////或者 控制器中创建表单//////////
use AppBundle\Entity\Post; #实体类
public function xxAction(Request $request)
{
   $form = $this->createFormBuilder(new Post()【, $options】)
		        ->add(‘name‘)
		        ->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);
    ...
}
##################################################################

## 表单提交 处理验证 ##
# 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->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) }}
///////或者 表单控件独立绘制////////
##################################################################
## 检测表单按钮点击 ##
$form->get(‘save‘)->isClicked(); //检测save按钮是否被点击

## 临时关闭客户端的required等校验功能 ##
{{ form(form, {‘attr‘: {‘novalidate‘: ‘novalidate‘}}) }}
或
submit按钮添加属性 ‘attr‘ => array(‘novalidate‘ => ‘novalidate‘),

## 表单字段配置 ##
$builder->add(‘名字‘, ‘类型‘, array(
‘label‘    =>    ‘yes‘,
‘attr‘     =>    array(‘class‘=>‘btn‘),

))
字段类型: text, date
时间: 2024-10-12 13:41:13

Symfony2 细节小计4的相关文章

traits技法小计

在学习算法导论的时候,对于各数据结构,自然是实现一个才算掌握,工具当然是template编程,但是自己的demo经常存在很多问题,比如没有给出迭代器啊,操作符重载不够啊等等设计上的问题,而某些问题实际上是从设计之初就该考虑的大框架,而非小细节.对于C++而言,STL无疑是最佳的参考资料,侯捷先生的STL源码剖析一书给我们良好的示范,而直接从第四章开始看会云里雾里,无法得其精髓,因此在学习算法之余决定尾随侯捷先生脚步,学习STL traits技法,从而可以从STL中学到更多的数据结构实现. 收获自

设计模式小计——23种设计模式3

责任链模式Chain of Responsibility 使多个对象都有机会处理请求,从而避免请求的发送者和接受者间的耦合关系,并沿着这条链传递请求,直到有对象处理它为止 责任链模式关键是建立链接关系,在链中决定谁来处理请求 //抽象处理者 public abstract class Handle{ private Handle nextHandle;//链的下一个节点 public final Response handleMessage(Request request){ Response

汽车仪表是如何计算总计里程和小计里程的?

现在汽车仪表大部分的总计里程和小计里程都是显示在屏幕上的,这包括段码屏.点阵屏.TFT彩屏等,虽然显示形式不一样,但是从业务需求和软件应用层的实现策略来讲,原理应该都是通用的.本文不涉及具体车型,仅对一般的业务逻辑作介绍,一是为了自己总结记录,二是期望吸引同行或爱好者交流. 1.总计里程 ODO(Total Odometer )即总计里程,顾名思义,主要作用是记录汽车总的行驶里程,一般来讲,在用户使用过程中是无法对其修改或清零的,因为它是对二手汽车价值评估的一项重要数值,当然随意篡改这一数据也是

设计模式小计——23种设计模式1

单例模式Singleton Pattern 确保类只有一个实例,而且自行实例化并向整个系统提供这个实例 public class Singleton{ private static final Singleton singleton = new Singleton(); private Singleton(){} public static Singleton getSingleton(){ return singleton; } } 节省内存开支,减少性能开销,应用启动产生单例对象,永久驻留内

设计模式小计——23种设计模式2

模板方法模式Template Method Pattern 定义一个操作的算法的框架,是的子类可以不改变算法结构即可重定义该算法一些特定步骤 public abstract class AbstractClass{//抽象模板类 protected abstract void method1();//算法步骤1 protected abstract void method2();//算法步骤2 public void templateMethod(){//模板方法,定义算法结构 this.met

Sql使用WITH ROLLUP 进行分类汇总及小计功能

效果如下: 测试代码如下: CREATE TABLE #test    (      Name VARCHAR(10) ,      [procedure] CHAR(1) ,      model VARCHAR(5) ,      quantity INT    ); INSERT  INTO #test        SELECT  'A' ,                '1' ,                'φ50' ,                500        UNI

RandomStrngUtils工具类小计

//产生5位长度的随机字符串,中文环境下是乱码 RandomStringUtils.random(5); //使用指定的字符生成5位长度的随机字符串 RandomStringUtils.random(5, new char[]{'a','b','c','d','e','f', '1', '2', '3'}); //生成指定长度的字母和数字的随机组合字符串 RandomStringUtils.randomAlphanumeric(5); //生成随机数字字符串 RandomStringUtils.

c++11小计

[capture] (parameters) mutable -> return-type { statement } " (parameters)" 和 "-> return-type"在不需要的情况下可省略. mutable:mutable修饰符.默认情况下,lambda函数总是一个const函数,mutable可以取消常量性.在使用该修饰符时,参数列表不可省略(即使为空). 在使用lambda函数的时候,如果需要捕捉的值成为lambda函数的常量,

小计使用多线程和gevent来提高celery性能及稳定性

前言: 有朋友问我,我那个任务队列是怎么实现,他的疑问其实主要是celery不支持多线程.先说说我那实现的方法,其实我的做法和celery.rq这样的框架很像的,都是把任务push到队列里面,然后pull取出任务而已,celery里面还可以取任务,我这个是通过传送uuid来实现的.   朋友问celery不支持多线程,那是他没有好好看文档.celery是支持多任务并发的,哎... 好好看文档呀. 原文:http://rfyiamcool.blog.51cto.com/1030776/153082