表单组件
编辑本页警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 2.3,现已不再维护。
读本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。
表单组件
Form组件允许您轻松地创建、处理和重用HTML表单。
Form组件是帮助您解决允许最终用户与数据交互和修改应用程序中的数据的问题的工具。虽然传统上是通过HTML表单来实现,但该组件专注于处理来自客户端和应用程序的数据,无论这些数据来自普通表单帖子还是API。
安装
你可以用两种不同的方式安装组件:
- 通过Composer安装(
ob娱乐下载symfony /形式
在Packagist); - 使用官方Git存储库(https://github.com/ob娱乐下载symfony/form).
然后,要求供应商/ autoload.php
文件以启用Composer提供的自动加载机制。否则,您的应用程序将无法找到这个Symfony组件的类。ob娱乐下载
配置
提示
如果您正在使用全堆栈的Symfony Framework, Form组件已经为ob娱乐下载您配置好了。在这种情况下,跳到表单组件.
在Syob娱乐下载mfony中,表单由对象表示,这些对象是通过使用形式的工厂.构建表单工厂很简单:
1 2 3
使用ob娱乐下载\组件\形式\形式;$formFactory=形式::createFormFactory ();
这个工厂已经可以用来创建基本的表单,但它缺乏对非常重要的特性的支持:
- 请求处理:支持请求处理和文件上传;
- CSRF保护:支持对跨站请求伪造(CSRF)攻击的保护;
- 模板:与模板层集成,允许您在呈现表单时重用HTML片段;
- 翻译:支持翻译错误消息,字段标签和其他字符串;
- 验证:与验证库集成,为提交的数据生成错误消息。
Symfob娱乐下载ony Form组件依赖于其他库来解决这些问题。大多数时候你会使用Twig和Symfonyob娱乐下载HttpFoundation, Translation和Validator组件,但您可以用您选择的不同库替换其中任何一个。
下面几节将解释如何将这些库插入表单工厂。
提示
请求处理
2.3
的handleRequest ()
方法是在Symfony 2.3中引入的。ob娱乐下载
要处理表单数据,需要调用handleRequest ()方法:
1
$形式->handleRequest ();
在幕后,这使用了一个NativeRequestHandler对象从正确的PHP超全局变量中读取数据。$ _POST
或$ _GET
)基于表单上配置的HTTP方法(POST是默认的)。
与HttpFoundation组件集成
如果你使用HttpFoundation组件,那么你应该添加HttpFoundationExtension到您的表单工厂:
1 2 3 4 5 6
使用ob娱乐下载\组件\形式\形式;使用ob娱乐下载\组件\形式\扩展\HttpFoundation\HttpFoundationExtension;$formFactory=形式::createFormFactoryBuilder ()->addExtension (新HttpFoundationExtension ())->getFormFactory ();
现在,当您处理表单时,您可以传递请求对象handleRequest ():
1
$形式->handleRequest ($请求);
请注意
有关HttpFoundation组件或如何安装它的更多信息,请参见HttpFoundation组件.
CSRF保护
针对CSRF攻击的保护内置在Form组件中,但是您需要显式地启用它或用自定义解决方案替换它。下面的代码片段向表单工厂添加了CSRF保护:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
使用ob娱乐下载\组件\形式\形式;使用ob娱乐下载\组件\形式\扩展\Csrf\CsrfExtension;使用ob娱乐下载\组件\形式\扩展\Csrf\CsrfProvider\SessionCsrfProvider;使用ob娱乐下载\组件\HttpFoundation\会话\会话;//从某处生成一个CSRF秘密$csrfSecret=“生成令牌> <”;//从HttpFoundation组件创建一个Session对象$会话=新会话();$csrfProvider=新SessionCsrfProvider ($会话,$csrfSecret);$formFactory=形式::createFormFactoryBuilder ()/ /……->addExtension (新CsrfExtension ($csrfProvider))->getFormFactory ();
为了保护您的应用程序免受CSRF攻击,您需要定义一个CSRF秘密。生成一个至少32个字符的随机字符串,将其插入到上面的代码片段中,并确保除了您的web服务器之外没有人可以访问该秘密。
在内部,这个扩展将自动添加一个隐藏字段到每个表单(称为_token
默认情况下),其值在绑定表单时自动生成并验证。
提示
如果你没有使用HttpFoundation组件,你可以使用DefaultCsrfProvider相反,它依赖于PHP的本地会话处理:
1 2 3
使用ob娱乐下载\组件\形式\扩展\Csrf\CsrfProvider\DefaultCsrfProvider;$csrfProvider=新DefaultCsrfProvider ($csrfSecret);
树枝模板
如果使用Form组件来处理HTML表单,则需要一种方法来轻松地将表单呈现为HTML表单字段(包括字段值、错误和标签)。如果你使用嫩枝作为模板引擎,Form组件提供了丰富的集成。
要使用该集成,您需要TwigBridge
,它提供了Twig和几个Symfony组件之间的集成。ob娱乐下载如果您正在使用Composer,您可以通过添加以下内容来安装最新的2.3版本需要
线路到您的composer.json
文件:
1 2 3 4 5
{“需要”: {“ob娱乐下载symfony / twig-bridge”:2.3“。*”}}
TwigBridge集成提供了几个功能树枝的功能帮助你渲染HTML小部件,标签和每个字段的错误(以及其他一些东西)。要配置集成,您需要引导或访问Twig并添加FormExtension:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
使用ob娱乐下载\组件\形式\形式;使用ob娱乐下载\桥\嫩枝\扩展\FormExtension;使用ob娱乐下载\桥\嫩枝\形式\TwigRenderer;使用ob娱乐下载\桥\嫩枝\形式\TwigRendererEngine;//包含渲染表单的所有默认标记的Twig文件//该文件与TwigBridge$defaultFormTheme=“form_div_layout.html.twig”;$vendorDir= realpath (__DIR__.“/ . . /供应商”);// TwigBridge库的路径,这样Twig就可以定位/ / form_div_layout.html。树枝文件$appVariableReflection=新\ ReflectionClass (“桥ob娱乐下载\ Symfony \ \树枝\ AppVariable”);$vendorTwigBridgeDir=目录名($appVariableReflection->getFileName ());//其他模板的路径$viewsDir= realpath (__DIR__.“/ . . /视图”);$嫩枝=新Twig_Environment (新Twig_Loader_Filesystem (数组($viewsDir,$vendorTwigBridgeDir.“/资源/视图/形式”)));$formEngine=新TwigRendererEngine (数组($defaultFormTheme));$formEngine->setEnvironment ($嫩枝);//添加FormExtension到Twig$嫩枝->addExtension (新FormExtension (新TwigRenderer ($formEngine,$csrfProvider)));//创建你的表单工厂$formFactory=形式::createFormFactoryBuilder ()/ /……->getFormFactory ();
你的详细资料树枝配置会有所不同,但目标始终是添加FormExtension到Twig,它允许您访问用于呈现表单的Twig函数。为此,首先需要创建一个TwigRendererEngine,在那里你定义你的形式的主题(即定义表单HTML标记的资源/文件)。
有关呈现表单的一般详细信息,请参见如何自定义表单渲染.
请注意
如果您使用Twig集成,请阅读“表单组件下面是有关所需翻译过滤器的详细信息。
翻译
如果您正在使用Twig与默认表单主题文件之一的集成(例如。form_div_layout.html.twig
),有2个Twig滤镜(反式
而且transChoice
),用于翻译表单标签、错误、选项文本和其他字符串。
要添加这些Twig过滤器,您可以使用内置的TranslationExtension它集成了Symfony的翻译组件,或者通过ob娱乐下载您自己的Twig扩展添加2个Twig过滤器。
要使用内置集成,请确保您的项目具有Symfony的Translation和ob娱乐下载配置组件安装。如果您正在使用Composer,您可以通过将以下内容添加到您的composer.json
文件:
1 2 3 4 5 6
{“需要”: {“ob娱乐下载symfony /翻译”:2.3“。*”,“ob娱乐下载symfony /配置”:2.3“。*”}}
接下来,添加TranslationExtension到你的Twig_Environment
实例:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21
使用ob娱乐下载\组件\形式\形式;使用ob娱乐下载\组件\翻译\翻译;使用ob娱乐下载\组件\翻译\加载程序\XliffFileLoader;使用ob娱乐下载\桥\嫩枝\扩展\TranslationExtension;//创建Translator$翻译=新翻译(“en”);//以某种方式加载一些翻译到它$翻译->addLoader (“xlf”,新XliffFileLoader ());$翻译->addResource (“xlf”,__DIR__.“/道路/ /翻译/ messages.en.xlf”,“en”);//添加TranslationExtension(给我们trans和transChoice过滤器)$嫩枝->addExtension (新TranslationExtension ($翻译));$formFactory=形式::createFormFactoryBuilder ()/ /……->getFormFactory ();
根据翻译的加载方式,现在可以将字符串键(如字段标签)及其翻译添加到翻译文件中。
有关翻译的详细信息,请参见翻译.
验证
Form组件与Symfony的Validator组件紧密集成(但可选)。ob娱乐下载如果您正在使用不同的解决方案进行验证,没问题!只需获取表单(数组或对象)提交/绑定的数据,并将其通过您自己的验证系统。
要使用与Symfony的Validator组件的集成,首ob娱乐下载先要确保它已安装在应用程序中。如果您正在使用Composer并希望安装最新的2.3版本,请将此添加到您的composer.json
:
1 2 3 4 5
{“需要”: {“ob娱乐下载symfony /验证器”:2.3“。*”}}
如果您不熟悉Symfony的Validator组件,请阅ob娱乐下载读更多有关它的信息:验证.Form组件附带一个ValidatorExtension类,它自动对绑定上的数据应用验证。然后将这些错误映射到正确的字段并呈现。
你与Validation组件的集成看起来像这样:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
使用ob娱乐下载\组件\形式\形式;使用ob娱乐下载\组件\形式\扩展\验证器\ValidatorExtension;使用ob娱乐下载\组件\验证器\验证;$vendorDir= realpath (__DIR__.“/ . . /供应商”);$vendorFormDir=$vendorDir.' ob娱乐下载/ symfony /形式/ symfony /组件/形式;$vendorValidatorDir=$vendorDir.' ob娱乐下载/ symfony /验证器/ symfony /组件/验证器”;//创建验证器-细节会有所不同$验证器=验证::createValidator ();//内核错误消息有内置的翻译$翻译->addResource (“xlf”,$vendorFormDir.' /资源/翻译/ validators.en.xlf ',“en”,“验证”);$翻译->addResource (“xlf”,$vendorValidatorDir.' /资源/翻译/ validators.en.xlf ',“en”,“验证”);$formFactory=形式::createFormFactoryBuilder ()/ /……->addExtension (新ValidatorExtension ($验证器))->getFormFactory ();
要了解更多信息,请跳转到表单组件部分。
访问表单工厂
您的应用程序只需要一个表单工厂,并且该工厂对象应该用于在应用程序中创建任何和所有表单对象。这意味着您应该在应用程序的某个中心引导部分创建它,然后在需要构建表单时访问它。
请注意
在本文档中,表单工厂始终是一个名为formFactory美元
.这里的重点是,您可能需要以某种更“全局”的方式创建这个对象,以便可以从任何地方访问它。
如何访问您的表单工厂取决于您自己。如果你用的是服务容器,然后您应该将表单工厂添加到容器中,并在需要时将其取出。如果您的应用程序使用全局变量或静态变量(通常不是一个好主意),那么您可以将对象存储在某个静态类或做类似的事情。
无论您如何构建应用程序,只要记住您应该只有一个表单工厂,并且您需要能够在整个应用程序中访问它。
创建简单表单
提示
如果您正在使用Symfony Frameob娱乐下载work,那么表单工厂将自动作为被调用的服务可用form.factory
.同样,默认基控制器类具有createFormBuilder ()方法,该方法是获取和调用表单工厂的快捷方式createBuilder
在上面。
创建表单是通过FormBuilder对象,在其中构建和配置不同的字段。表单构建器是从表单工厂创建的。
- 独立使用
- 框架的使用
1 2 3 4 5 6 7 8
$形式=$formFactory->createBuilder ()->add (“任务”,“文本”)->add (“dueDate”,“日期”)->getForm ();var_dump ($嫩枝->呈现(“new.html.twig”,数组(“形式”= >$形式->createView ())));
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
/ / src / Acme / TaskBundle /控制器/ DefaultController.php名称空间Acme\TaskBundle\控制器;使用ob娱乐下载\包\FrameworkBundle\控制器\控制器;使用ob娱乐下载\组件\HttpFoundation\请求;类DefaultController扩展控制器{公共函数newAction(请求$请求){// createFormBuilder是获取“表单工厂”的快捷方式//然后调用"createBuilder()$形式=$这->createFormBuilder ()->add (“任务”,“文本”)->add (“dueDate”,“日期”)->getForm ();返回$这->呈现(“AcmeTaskBundle:违约:new.html.twig”,数组(“形式”= >$形式->createView ()));}}
如您所见,创建表单就像编写食谱:您调用添加
对于您想要创建的每个新字段。的第一个参数添加
是字段的名称,第二个是字段“类型”。Form组件提供了很多内置类型.
设置默认值
如果你需要你的表单加载一些默认值(或者你正在构建一个“编辑”表单),在创建你的表单构建器时简单地传入默认数据:
- 独立使用
- 框架的使用
1 2 3 4 5 6 7 8
$违约=数组(“dueDate”= >新\ DateTime (“明天”),);$形式=$formFactory->createBuilder (“形式”,$违约)->add (“任务”,“文本”)->add (“dueDate”,“日期”)->getForm ();
1 2 3 4 5 6 7 8
$违约=数组(“dueDate”= >新\ DateTime (“明天”),);$形式=$这->createFormBuilder ($违约)->add (“任务”,“文本”)->add (“dueDate”,“日期”)->getForm ();
提示
在本例中,默认数据是一个数组。以后,当你使用data_class选项将数据直接绑定到对象,则默认数据将是该对象的一个实例。
渲染表单
现在已经创建了表单,下一步是呈现它。这是通过向模板传递一个特殊的表单“view”对象来实现的(注意形式- > createView ()
在上面的控制器中),并使用一组表单帮助函数:
1 2 3 4 5
{{form_start(form)}}{{form_widget(form)}}<输入类型=“提交”/>{{form_end(form)}}
就是这样!通过印刷form_widget(形式)
,将呈现表单中的每个字段,以及标签和错误消息(如果有的话)。尽管这很简单,但它(目前)还不是很灵活。通常,您希望单独呈现每个表单字段,以便可以控制表单的外观。你会在"形式”一节。
改变窗体的方法和动作
2.3
配置表单方法和动作的功能是在Symfony 2.3中引入的。ob娱乐下载
默认情况下,表单被提交给使用HTTP POST请求呈现表单的同一个URI。属性可以更改此行为字段类型而且字段类型选项(方法
选项也被使用handleRequest ()
确定表单是否已提交):
- 独立使用
- 框架的使用
1 2 3 4 5 6
$formBuilder=$formFactory->createBuilder (“形式”,零,数组(“行动”= >“/搜索”,“方法”= >“得到”));/ /……
1 2 3 4 5 6 7 8 9 10 11
/ /……公共函数searchAction(){$formBuilder=$这->createFormBuilder (零,数组(“行动”= >“/搜索”,“方法”= >“得到”));/ /……}
处理递交表格
要处理表单提交,请使用handleRequest ()方法:
- 独立使用
- 框架的使用
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\RedirectResponse;$形式=$formFactory->createBuilder ()->add (“任务”,“文本”)->add (“dueDate”,“日期”)->getForm ();$请求=请求::createFromGlobals ();$形式->handleRequest ($请求);如果($形式->isValid ()) {$数据=$形式->getData ();/ /……执行一些操作,例如将数据保存到数据库$响应=新RedirectResponse (“成功/任务/”);$响应->准备($请求);返回$响应->send ();}/ /……
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21
/ /……公共函数newAction(请求$请求){$形式=$这->createFormBuilder ()->add (“任务”,“文本”)->add (“dueDate”,“日期”)->getForm ();$形式->handleRequest ($请求);如果($形式->isValid ()) {$数据=$形式->getData ();/ /……执行一些操作,例如将数据保存到数据库返回$这->重定向($这->generateUrl (“task_success”));}/ /……}
这定义了一个常见的“workflow”表单,它包含3种不同的可能性:
- 在最初的GET请求(即当用户“冲浪”到你的页面时),构建你的表单并渲染它;
如果请求是POST,则处理提交的数据(通过handleRequest ()
).然后:
- 如果表单无效,重新呈现表单(现在将包含错误);
- 如果表单有效,则执行一些操作并重定向。
幸运的是,您不需要决定是否提交了表单。只需要将当前请求传递给handleRequest ()
方法。然后,Form组件将为您完成所有必要的工作。
表单验证
向表单添加验证的最简单方法是约束
选项时,建立每个字段:
- 独立使用
- 框架的使用
12 3 4 5 6 7 8 9 10 11 12 13 14
使用ob娱乐下载\组件\验证器\约束\NotBlank;使用ob娱乐下载\组件\验证器\约束\类型;$形式=$formFactory->createBuilder ()->add (“任务”,“文本”,数组(“约束”= >新NotBlank ()))->add (“dueDate”,“日期”,数组(“约束”= >数组(新NotBlank (),新类型(“\ DateTime”),)))->getForm ();
12 3 4 5 6 7 8 9 10 11 12 13 14
使用ob娱乐下载\组件\验证器\约束\NotBlank;使用ob娱乐下载\组件\验证器\约束\类型;$形式=$这->createFormBuilder ()->add (“任务”,“文本”,数组(“约束”= >新NotBlank ()))->add (“dueDate”,“日期”,数组(“约束”= >数组(新NotBlank (),新类型(“\ DateTime”),)))->getForm ();
当表单被绑定时,这些验证约束将被自动应用,错误将显示在错误字段旁边。
请注意
有关所有内置验证约束的列表,请参见验证约束参考.
访问表单错误
您可以使用getErrors ()方法访问错误列表。每个元素都是FormError对象:
12 3 4 5 6 7 8 9 10 11 12 13 14
$形式=……;/ /……//一个FormError对象数组,但是只有错误附加到这个数组//表单级别(例如:“全球错误)$错误=$形式->getErrors ();//一个FormError对象的数组,但是只有附加到// firstName字段$错误=$形式[“firstName”]->getErrors ();//整个表单树的所有错误的字符串表示$错误=$形式->getErrorsAsString ();
请注意
如果您启用error_bubbling选项在一个字段,调用getErrors ()
将包含来自该字段的错误。但是,无法确定错误最初附加到哪个字段。