表单组件

表单组件

Form组件允许您创建、处理和重用表单。

Form组件是一种工具,可以帮助您解决允许最终用户在应用程序中与数据交互和修改数据的问题。虽然传统上这是通过HTML表单实现的,但该组件专注于处理来往于客户机和应用程序的数据,无论这些数据是来自普通表单post还是来自API。

安装

1
$作曲家需要Symfony /表格欧宝娱乐app下载地址

笔记

如果在Symfony应用程序之外安装此组件,则必须要求欧宝娱乐app下载地址供应商/ autoload.php.以启用Composer提供的类自动加载机制。读这篇文章为更多的细节。

配置

也可以看看

本文介绍如何在任何PHP应用程序中使用表单功能作为独立组件。阅读形式文章学习如何在Symfony应用程序中使用它。欧宝娱乐app下载地址

在Sy欧宝娱乐app下载地址mfony中,表单由对象表示,并且通过使用a构建这些对象形式的工厂。使用工厂方法构建表单工厂表单:: CreateFormFactory.

使用欧宝娱乐app下载地址symfony \ component \ form \ forms;$ FormFactory.=形式::CreateFormFactory.();

这个工厂已经可以用来创建基本的表单,但它缺乏对非常重要的功能的支持:

  • 请求处理:支持请求处理和文件上传;
  • CSRF保护:支持防止跨站点请求 - 伪造(CSRF)攻击;
  • 模板:与模板层的集成,允许在呈现表单时重用HTML片段;
  • 翻译:支持翻译错误消息,字段标签和其他字符串;
  • 验证:与验证库集成,为提交的数据生成错误消息。

Symf欧宝娱乐app下载地址ony表单组件依赖于其他库来解决这些问题。大多数时候你将使用树枝和symfony欧宝娱乐app下载地址httpfoundation翻译验证器组件,但您可以使用其他库替换其中的任何一个。

以下部分解释了如何将这些库插入到表单工厂中。

小费

有关工作示例,请参见https://github.com/webmozart/standalone-forms

请求处理

要处理表单数据,需要调用handlerequest()方法:

$表格->handleRequest();

在幕后,它使用欧宝娱乐app下载地址symfony \ component \ form \ nativeRequestHandler对象从正确的PHP超全局变量(例如。$ _POST$ _get.),基于在表单上配置的HTTP方法(默认为POST)。

也可以看看

如果您在提交表单或将哪些数据传递给它时,您需要更多控制,使用submit()方法来处理表单提交

CSRF保护

FSRF攻击的保护内置于表单组件中,但您需要明确启用它或用自定义解决方案替换它。如果要使用内置支持,请首先安装安全性CSRF组件:

1
$作曲家需要symfony / se欧宝娱乐app下载地址curity-csrf

下面的代码片段为表单工厂添加了CSRF保护:

使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ csrf \ csrfextension;使用欧宝娱乐app下载地址symfony \ component \ form \ forms;使用欧宝娱乐app下载地址symfony \ component \ httpfoundation \ session \ session;使用欧宝娱乐app下载地址Symfony \ \安全\ Csrf \ CsrfTokenManager组件;使用欧宝娱乐app下载地址Symfony \ \安全\ Csrf \ TokenGenerator \ UriSafeTokenGenerator组件;使用欧宝娱乐app下载地址Symfony \ \安全\ Csrf \ TokenStorage \ SessionTokenStorage组件;//从HttpFoundation组件创建一个Session对象$课程=会话();$ csrfgenerator=UriSafeTokenGenerator();csrfStorage美元=sessionTokenStorage.$课程);$ CSRFManager.=CSRftoknManager.$ csrfgeneratorcsrfStorage美元);$ FormFactory.=形式::createFormFactoryBuilder()/ /……->addExtensioncsrfextension.$ CSRFManager.))->getFormFactory.();

在内部,此扩展将自动向每个表单添加隐藏字段(调用_Token.默认情况下)其值由CSRF生成器自动生成并在绑定表单时验证。

小费

如果您未使用HttpFoundation组件,则可以使用欧宝娱乐app下载地址symfony \ component \ security \ csrf \ tokenstorage \ nativessionTokenStorage相反,依赖于PHP的本机会话处理:

使用欧宝娱乐app下载地址symfony \ component \ security \ csrf \ tokenstorage \ nativessionTokenStorage;csrfStorage美元=NativeSessionTokenStorage();/ /……

您可以使用每个表单禁用CSRF保护csrf_protection选择:

使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ core \ type \ form type;$表格=$ FormFactory.->createBuilderformtype.::班级[“csrf_protection”= >])->getForm.();

树枝模板

如果您正在使用表单组件来处理HTML表单,则需要一种方法来将表单呈现为HTML表单字段(完成字段值,错误和标签)。如果你使用嫩枝作为模板引擎,Form组件提供了丰富的集成。

要使用这个集成,你需要twig桥接器,它提供了twig和几个Symfony组件之间的集成:欧宝娱乐app下载地址

1
$作曲家需要Symfony / Tw欧宝娱乐app下载地址ig-Bridge

Twigbridge集成为您提供了几个枝函数这有助于您为每个字段(以及其他一些东西)呈现HTML窗口小部件,标签,帮助和错误。要配置集成,您需要引导或访问Twig并添加欧宝娱乐app下载地址symfony \ bridge \ twig \ extension \ formextension

使用欧宝娱乐app下载地址symfony \ bridge \ twig \ extension \ formextension;使用欧宝娱乐app下载地址symfony \ bridge \ twig \ form \ twigridenererengine;使用欧宝娱乐app下载地址Symfony \组件\ \ FormRenderer形式;使用欧宝娱乐app下载地址symfony \ component \ form \ forms;使用树枝\环境;使用树枝\装载机\ FilesystemLoader;使用Twig \ Runtimeloader \ FactoryRuntimeLoader;// Twig文件,包含所有用于呈现表单的默认标记//这个文件配有twigbridgedefaultFormTheme美元=“form_div_layout.html.twig”;$ vendordirectory.=realpath__dir__“/ . . /供应商”);// twigbridge库的路径,所以树枝可以定位/ / form_div_layout.html。树枝文件appVariableReflection美元=\ restectionclass.'\欧宝娱乐app下载地址 symfony \ bridge \ twig \ appvariable');$ vendortwigbridgedirectory.=目录名appVariableReflection美元->getFileName());//其他模板的路径viewsDirectory美元=realpath__dir__'/../views');美元的树枝=环境filesystemloader.([viewsDirectory美元$ vendortwigbridgedirectory.“/资源/视图/形式”)));$ formengine.=TwigRendererEngine([defaultFormTheme美元),美元的树枝);美元的树枝->addruntimeloader.FactoryRuntimeLoader([FormRenderer.::班级= >函数()使用$ formengine.$ CSRFManager.{返回FormRenderer.$ formengine.$ CSRFManager.);},)));// ...(有关详细信息,请参阅以前的CSRF保护部分)//添加FormExtension到Twig美元的树枝->addExtension框架());//创建一个表单工厂$ FormFactory.=形式::createFormFactoryBuilder()/ /……->getFormFactory.();

1.30新版功能:Twig \ Runtimeloader \ FactoryRuntimeLoader在Twig 1.30中引入。

你的确切细节枝条配置会有所不同,但目标总是加入欧宝娱乐app下载地址symfony \ bridge \ twig \ extension \ formextension到Twig,它可以让您访问渲染表单的枝章函数。为此,您首先需要创建一个欧宝娱乐app下载地址symfony \ bridge \ twig \ form \ twigridenererengine,你定义你的表格主题(即定义形式HTML标记的资源/文件)。

有关呈现形式的一般细节,请参阅如何自定义表单呈现

笔记

如果您使用枝条集成,请阅读“翻译“下面有关所需翻译过滤器的详细信息。

翻译

如果您正在使用Twig集成与一个默认的表单主题文件(例如。form_div_layout.html.twig.),有一个树枝滤波器(trans),用于翻译表单标签、错误、选项文本和其他字符串。

要添加trans缩束过滤器,您可以使用内置欧宝娱乐app下载地址Symfony \ \树枝\ \ TranslationExtension扩展的桥梁通过您自己的Twig扩展,它与Symfon欧宝娱乐app下载地址y的翻译组件集成,或者添加枝条滤波器。

要使用内置集成,请确保您的项目有Symfony的翻译和欧宝娱乐app下载地址配置安装了组件:

1
$Composer要求Symfony欧宝娱乐app下载地址 /翻译Symfony / Config

接下来,添加欧宝娱乐app下载地址Symfony \ \树枝\ \ TranslationExtension扩展的桥梁到你的树枝\环境实例:

使用欧宝娱乐app下载地址Symfony \ \树枝\ \ TranslationExtension扩展的桥梁;使用欧宝娱乐app下载地址symfony \ component \ form \ forms;使用欧宝娱乐app下载地址Symfony翻译\组件\ \程序\ XliffFileLoader;使用欧宝娱乐app下载地址symfony \ component \ translation \ translator;//创建Translator$译者=翻译“en”);//加载一些翻译到它$译者->addLoader“xlf”XliffFileLoader());$译者->addResource.“xlf”__dir__'/path/to/translations/messages.en.xlf'“en”);//添加TranslationExtension(它给了我们trans过滤器)美元的树枝->addExtension翻译extension.$译者));$ FormFactory.=形式::createFormFactoryBuilder()/ /……->getFormFactory.();

根据如何加载翻译,您现在可以添加字符串键,例如现场标签,以及他们的翻译文件的翻译。

有关翻译的更多细节,请参见翻译

验证

表单组件与Symfony的验证器组件紧密(但可选)集成。欧宝娱乐app下载地址如果您正在使用不同的验证解决方案,请没有问题!使用表单的提交/绑定数据(这是一个数组或对象),并通过自己的验证系统。

要使用与symfony的验证器组件的集成,请首先确保它安欧宝娱乐app下载地址装在您的应用程序中:

1
$作曲家需要symfony /验证器欧宝娱乐app下载地址

如果您不熟悉Symfony的验证器组件,请阅读更多条件:欧宝娱乐app下载地址验证。Form组件附带一个欧宝娱乐app下载地址symfony \ component \ form \ extension \ validator \ validatorextension类,它会自动对绑定上的数据应用验证。然后将这些错误映射到正确的字段并呈现。

你与Validation组件的集成看起来像这样:

使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ validator \ validatorextension;使用欧宝娱乐app下载地址symfony \ component \ form \ forms;使用欧宝娱乐app下载地址Symfony \ Component \ Validator \验证;$ vendordirectory.=realpath__dir__“/ . . /供应商”);$ VendorFormDirectory.=$ vendordirectory.“/欧宝娱乐app下载地址 symfony /形式”;vendorValidatorDirectory美元=$ vendordirectory.“/欧宝娱乐app下载地址 symfony /验证器”;//创建验证器 - 详细信息将有所不同美元的验证器=验证::createValidator();//核心错误信息有内置的翻译$译者->addResource.“xlf”$ VendorFormDirectory.' /资源/翻译/ validators.en.xlf '“en”“验证”);$译者->addResource.“xlf”vendorValidatorDirectory美元' /资源/翻译/ validators.en.xlf '“en”“验证”);$ FormFactory.=形式::createFormFactoryBuilder()/ /……->addExtensionAdvanyAtoreXtense.美元的验证器))->getFormFactory.();

要了解更多,请跳到表单验证部分。

访问表格工厂

您的应用程序只需要一个表单工厂,并且应该使用这个工厂对象来创建应用程序中的任何和所有表单对象。这意味着您应该在应用程序的某个中央引导部分中创建它,然后在需要构建表单时访问它。

笔记

在本文档中,表单工厂始终是一个调用的局部变量$ FormFactory.。这里的点是您可能需要以一些“全局”方式创建此对象,以便您可以从任何地方访问它。

究竟你如何获得你的一个表格工厂的访问取决于您。如果您正在使用服务容器(如用DependencyInjection组件),然后应该将表单工厂添加到容器中,并在需要时将其取出。如果您的应用程序使用全局或静态变量(通常不是一个好主意),那么您可以将对象存储在某个静态类上或做类似的事情。

无论您如何架构应用程序,都记得您应该只有一个表单工厂,并且您需要在整个应用程序中访问它。

创建一个简单的形式

小费

如果您使用的是Symfony框架,那么表欧宝娱乐app下载地址单工厂将自动为称为服务Form.Factory.。此外,默认的基控制器类具有createFormBuilder ()方法,这是获取表单工厂和调用的快捷方式createBuilder ()在上面。

创建表单是通过a完成的欧宝娱乐app下载地址symfony \ component \ form \ formbuilder对象,在其中构建和配置不同的字段。表单构建器是从表单工厂创建的。

  • 独立使用
    12 3 4 5 6 7 8 9 10 11 12 13
    使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ core \ type \ texttype;使用欧宝娱乐app下载地址Symfony \组件\ \ \ \核心类型的扩展\ DateType形式;/ /……$表格=$ FormFactory.->createBuilder()->添加'任务'TextType.::班级->添加'到期日'DateType.::班级->getForm.();var_dump美元的树枝->渲染'new.html.twig'['形式'= >$表格->createview.(),)));
  • 框架的使用
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 21 21 22 23 24 24 22
    // src / controller / taskcontroller.php名称空间App \控制器;使用欧宝娱乐app下载地址symfony \ bundle \ frameworkbundle \ controller \ AbstractController;使用欧宝娱乐app下载地址Symfony \ HttpFoundation \ \组件请求;使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ core \ type \ texttype;使用欧宝娱乐app下载地址Symfony \组件\ \ \ \核心类型的扩展\ DateType形式;班级TaskController.延伸AbstractController{公共函数要求美元的请求{// createFormBuilder是获取“表单工厂”的快捷方式//然后调用createBuilder()$表格=$这一点->createFormBuilder()->添加'任务'TextType.::班级->添加'到期日'DateType.::班级->getForm.();返回$这一点->渲染“任务/ new.html.twig”['形式'= >$表格->createview.(),]);}}

如您所见,创建表单就像编写菜谱:您调用add ()对于您要创建的每个新字段。第一个论点add ()是您字段的名称,第二个是完全限定的类名。表单组件附带了很多内置类型

现在您已经构建了表单,请学习如何构建渲染它,处理表单提交

设置默认值

如果你需要表单加载一些默认值(或者你正在构建一个“编辑”表单),在创建表单构建器时传递默认数据:

  • 独立使用
    12 3 4 5 6 7 8 9 10 11 12 13 14
    使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ core \ type \ form type;使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ core \ type \ texttype;使用欧宝娱乐app下载地址Symfony \组件\ \ \ \核心类型的扩展\ DateType形式;/ /……$默认值=['到期日'= >\ DateTime“明天”),];$表格=$ FormFactory.->createBuilderformtype.::班级$默认值->添加'任务'TextType.::班级->添加'到期日'DateType.::班级->getForm.();
  • 框架的使用
    12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
    // src / controller / defaultController.php名称空间App \控制器;使用欧宝娱乐app下载地址symfony \ bundle \ frameworkbundle \ controller \ AbstractController;使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ core \ type \ texttype;使用欧宝娱乐app下载地址Symfony \组件\ \ \ \核心类型的扩展\ DateType形式;班级DefaultController延伸AbstractController{公共函数要求美元的请求{$默认值=['到期日'= >\ DateTime“明天”),];$表格=$这一点->createFormBuilder$默认值->添加'任务'TextType.::班级->添加'到期日'DateType.::班级->getForm.();/ /……}}

小费

在本例中,默认数据是一个数组。稍后,当您使用data_class选项要将数据绑定到对象,默认数据将是该对象的实例。

呈现形式

既然表单已经创建,下一步是渲染它。这是通过将特殊形式的“查看”对象传递给您的模板来完成的(注意形式- > createView ()在上面的控制器中)和使用一组表单辅助函数

1 2 3 4 5
{{form_start.形式}}{{form_widget.形式}}<输入类型=“提交”/>{{form_end.形式}}
. . / _images / simple-form.png

就是这样!通过印刷form_widget(表格),表单中的每个字段都呈现,以及标签和错误消息(如果有一个)。虽然这方便,但它不是很灵活(又有)。通常,您需要单独呈现每个表单字段,以便控制表单的外观。你会学会如何做到这一点表单定制篇文章。

改变表单的方法和动作

默认情况下,表单将提交到与HTTP POST请求呈现表单的相同URI。可以使用此行为来更改行动方法选项(本方法选项也被使用handlerequest()确定表格是否已提交):

  • 独立使用
    1 2 3 4 5 6 7 8 9 10
    使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ core \ type \ form type;/ /……formBuilder美元=$ FormFactory.->createBuilderformtype.::班级['行动'= >“/搜索”“方法”= >'得到']);/ /……
  • 框架的使用
    12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
    // src / controller / defaultController.php名称空间App \控制器;使用欧宝娱乐app下载地址symfony \ bundle \ frameworkbundle \ controller \ AbstractController;使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ core \ type \ form type;班级DefaultController延伸AbstractController{公共函数搜索(){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 25 26 27 28
    使用欧宝娱乐app下载地址Symfony \ HttpFoundation \ \组件请求;使用欧宝娱乐app下载地址Symfony \ \ HttpFoundation \ RedirectResponse组件;使用欧宝娱乐app下载地址Symfony \组件\ \ \ \核心类型的扩展\ DateType形式;使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ core \ type \ texttype;/ /……$表格=$ FormFactory.->createBuilder()->添加'任务'TextType.::班级->添加'到期日'DateType.::班级->getForm.();美元的请求=要求::createfromglobals.();$表格->handleRequest美元的请求);如果$表格->isSubmitted()&&$表格->isValid()){元数据=$表格->getData();/ /……执行一些操作,例如将数据保存到数据库中美元的反应=重新考虑'/任务/成功');美元的反应->准备美元的请求);返回美元的反应->发送();}/ /……
  • 框架的使用
    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
    // src / controller / taskcontroller.php名称空间App \控制器;使用欧宝娱乐app下载地址symfony \ bundle \ frameworkbundle \ controller \ AbstractController;使用欧宝娱乐app下载地址Symfony \组件\ \ \ \核心类型的扩展\ DateType形式;使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ core \ type \ texttype;班级TaskController.延伸AbstractController{公共函数要求美元的请求{$表格=$这一点->createFormBuilder()->添加'任务'TextType.::班级->添加'到期日'DateType.::班级->getForm.();$表格->handleRequest美元的请求);如果$表格->isSubmitted()&&$表格->isValid()){元数据=$表格->getData();/ /……执行一些操作,例如将数据保存到数据库中返回$这一点->redirectToRoute“task_success”);}/ /……}}

这定义了常见的形式“工作流”,其中包含3种不同的可能性:

  1. 在初始获取请求(即,当用户“冲浪”到您的页面时),构建表单并渲染;

如果请求是帖子,请处理提交的数据(通过handlerequest())。然后:

  1. 如果表单无效,重新呈现表单(现在将包含错误);
  2. 如果表单有效,请执行一些操作并重定向。

幸运的是,您不需要决定是否提交了表单。将当前请求传递给handlerequest()方法。然后,表单组件将为您做所有必要的工作。

表单验证

将验证添加到您的表单中最简单的方法是通过约束构建每个字段时的选项:

  • 独立使用
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
    使用欧宝娱乐app下载地址symfony \ component \ validator \ constraints \ notlank;使用欧宝娱乐app下载地址symfony \ component \ validator \ constraints \类型;使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ core \ type \ texttype;使用欧宝娱乐app下载地址Symfony \组件\ \ \ \核心类型的扩展\ DateType形式;$表格=$ FormFactory.->createBuilder()->添加'任务'TextType.::班级[“约束”= >不发(),])->添加'到期日'DateType.::班级[“约束”= >[不发(),类型\ DateTime::班级),]])->getForm.();
  • 框架的使用
    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
    // src / controller / defaultController.php名称空间App \控制器;使用欧宝娱乐app下载地址symfony \ bundle \ frameworkbundle \ controller \ AbstractController;使用欧宝娱乐app下载地址symfony \ component \ validator \ constraints \ notlank;使用欧宝娱乐app下载地址symfony \ component \ validator \ constraints \类型;使用欧宝娱乐app下载地址Symfony \组件\ \ \ \核心类型的扩展\ DateType形式;使用欧宝娱乐app下载地址symfony \ component \ form \ extension \ core \ type \ texttype;班级DefaultController延伸AbstractController{公共函数要求美元的请求{$表格=$这一点->createFormBuilder()->添加'任务'TextType.::班级[“约束”= >不发(),])->添加'到期日'DateType.::班级[“约束”= >[不发(),类型\ DateTime::班级),]])->getForm.();/ /……}}

绑定表单时,将自动应用这些验证约束,错误将显示在“错误”的字段旁边。

笔记

有关所有内置验证约束的列表,请参见验证约束参考

访问表单错误

你可以使用geterrors()方法来访问错误列表。它返回一个欧宝娱乐app下载地址Symfony \组件\ \ FormErrorIterator形式实例:

$表格=......;/ /……//一个FormErrorIterator实例,但只有错误附加到此//表单级别(例如全局错误)美元的错误=$表格->getErrors();// formerRorITerator实例,但仅附加到的错误/ /“firstName”字段美元的错误=$表格[“firstName”]->getErrors();//扁平结构中的FormErrorIterator实例//使用getOrigin()确定导致错误的表单美元的错误=$表格->getErrors真正的);//一个FormErrorIterator实例,表示表单树结构美元的错误=$表格->getErrors真正的);

结算方式错误

属性可以手动清除任何错误clearerrors()方法。当您想验证表单而不向用户显示验证错误时,这是​​有用的(即在部分AJAX提交期间或动态表单修改)。

因为清除错误使表单有效,clearerrors()仅在测试表格是否有效后才应在调用后调用。

这项工作,包括代码样本,是在一个创作共用BY-SA 3.0执照。