{"id":1146,"date":"2025-06-12T14:12:32","date_gmt":"2025-06-12T06:12:32","guid":{"rendered":"https:\/\/www.zhaozhao123.cn\/php\/php-application-manual\/symfony\/1146.html"},"modified":"2025-06-12T14:12:32","modified_gmt":"2025-06-12T06:12:32","slug":"%e5%9c%a8symfony%e7%9a%84%e8%a1%a8%e5%8d%95%e7%bb%84%e4%bb%b6%e4%b8%ad%e5%b7%a5%e4%bd%9c%ef%bc%9a%e5%ae%9e%e7%94%a8%e6%8c%87%e5%8d%97","status":"publish","type":"my1js","link":"https:\/\/www.zhaozhao123.cn\/php\/my1js\/1146.html","title":{"rendered":"\u5728Symfony\u7684\u8868\u5355\u7ec4\u4ef6\u4e2d\u5de5\u4f5c\uff1a\u5b9e\u7528\u6307\u5357"},"content":{"rendered":"<div class=\"wp-block-columns p-0 border is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-columns px-4 py-3 border-bottom has-background is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\" style=\"background:linear-gradient(243deg,rgb(238,238,238) 0%,rgba(58,166,242,0.15) 100%)\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-6c531013 wp-block-group-is-layout-flex\">\r\n<figure class=\"wp-block-image size-thumbnail is-resized is-style-rounded is-style-rounded--1\"><img decoding=\"async\" src=\"https:\/\/www.zhaozhao123.cn\/myitems\/images\/sites16\/2025\/06\/dyA-1-400x300.jpg\" alt=\"Bug&#32534;&#35793;&#29422;\" class=\"wp-image-1842\" style=\"object-fit:cover;width:30px;height:30px\"><\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading my-0\" style=\"font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.175), 1rem);\">Bug&#32534;&#35793;&#29422;<\/h2>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"wp-block-columns px-xl-5 px-4 py-xl-4 py-3 is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<p>&#12298;Symfony&#34920;&#21333;&#32452;&#20214;&#23454;&#29992;&#25351;&#21335;&#12299;<\/p>\n<p>&#22312;&#29616;&#20195;Web&#24320;&#21457;&#20013;&#65292;&#34920;&#21333;&#22788;&#29702;&#26159;&#19981;&#21487;&#25110;&#32570;&#30340;&#19968;&#37096;&#20998;&#12290;Symfony&#30340;&#34920;&#21333;&#32452;&#20214;&#25552;&#20379;&#20102;&#20016;&#23500;&#30340;&#21151;&#33021;&#21644;&#28789;&#27963;&#24615;&#65292;&#20351;&#24471;&#24320;&#21457;&#32773;&#21487;&#20197;&#36731;&#26494;&#22320;&#21019;&#24314;&#12289;&#39564;&#35777;&#21644;&#22788;&#29702;&#29992;&#25143;&#36755;&#20837;&#12290;&#26412;&#25991;&#23558;&#20171;&#32461;&#22914;&#20309;&#20351;&#29992;Symfony&#30340;&#34920;&#21333;&#32452;&#20214;&#65292;&#21253;&#25324;&#22522;&#26412;&#27010;&#24565;&#12289;&#24120;&#29992;&#23646;&#24615;&#21644;&#31034;&#20363;&#20195;&#30721;&#12290;<\/p>\n<h3>1. &#22522;&#26412;&#27010;&#24565;<\/h3>\n<h4>&#34920;&#21333;&#23545;&#35937;&#65288;Form Object&#65289;<\/h4>\n<p>&#34920;&#21333;&#23545;&#35937;&#26159;&#29992;&#20110;&#23384;&#20648;&#34920;&#21333;&#25968;&#25454;&#30340;&#23545;&#35937;&#12290;&#36890;&#36807;&#23450;&#20041;&#19968;&#20010;&#31867;&#26469;&#34920;&#31034;&#34920;&#21333;&#25968;&#25454;&#65292;&#24182;&#20351;&#29992;<code>FormBuilder<\/code>&#26469;&#26500;&#24314;&#34920;&#21333;&#23383;&#27573;&#12290;<\/p>\n<pre><code class=\"language-php\">\/\/ src\/Entity\/User.php\nnamespace AppEntity;\n\nuse SymfonyComponentValidatorConstraints as Assert;\n\nclass User\n{\n    private $id;\n    private $username;\n    private $email;\n\n    \/\/ Getters and setters\n}<\/code><\/pre>\n<pre><code class=\"language-php\">\/\/ src\/Form\/Type\/UserType.php\nnamespace AppFormType;\n\nuse SymfonyComponentFormAbstractType;\nuse SymfonyComponentFormExtensionCoreTypeTextType;\nuse SymfonyComponentFormExtensionCoreTypeEmailType;\nuse SymfonyComponentOptionsResolverOptionsResolver;\n\nclass UserType extends AbstractType\n{\n    public function buildForm(FormBuilderInterface $builder, array $options)\n    {\n        $builder\n            -&gt;add('username', TextType::class, [\n                'label' =&gt; 'Username',\n                'constraints' =&gt; [\n                    new AssertNotBlank(),\n                    new AssertLength(min: 3),\n                ],\n            ])\n            -&gt;add('email', EmailType::class, [\n                'label' =&gt; 'Email',\n                'constraints' =&gt; [\n                    new AssertNotBlank(),\n                    new AssertEmail(),\n                ],\n            ]);\n    }\n\n    public function configureOptions(OptionsResolver $resolver)\n    {\n        $resolver-&gt;setDefaults([\n            'data_class' =&gt; User::class,\n        ]);\n    }\n}<\/code><\/pre>\n<h4>&#27169;&#22411;&#32465;&#23450;&#65288;Model Binding&#65289;<\/h4>\n<p>&#27169;&#22411;&#32465;&#23450;&#26159;&#25351;&#23558;&#34920;&#21333;&#25968;&#25454;&#33258;&#21160;&#26144;&#23556;&#21040;&#23454;&#20307;&#31867;&#20013;&#12290;<\/p>\n<pre><code class=\"language-php\">\/\/ src\/Controller\/UserController.php\nnamespace AppController;\n\nuse AppEntityUser;\nuse AppFormTypeUserType;\nuse SymfonyBundleFrameworkBundleControllerAbstractController;\nuse SymfonyComponentHttpFoundationRequest;\nuse SymfonyComponentHttpFoundationResponse;\n\nclass UserController extends AbstractController\n{\n    public function register(Request $request): Response\n    {\n        $user = new User();\n        $form = $this-&gt;createForm(UserType::class, $user);\n\n        if ($form-&gt;isSubmitted() &amp;&amp; $form-&gt;isValid()) {\n            \/\/ &#22788;&#29702;&#34920;&#21333;&#25968;&#25454;\n            $entityManager = $this-&gt;getDoctrine()-&gt;getManager();\n            $entityManager-&gt;persist($user);\n            $entityManager-&gt;flush();\n\n            return $this-&gt;redirectToRoute('home');\n        }\n\n        return $this-&gt;render('register.html.twig', [\n            'form' =&gt; $form-&gt;createView(),\n        ]);\n    }\n}<\/code><\/pre>\n<h3>2. &#24120;&#29992;&#23646;&#24615;<\/h3>\n<ul>\n<li><strong><code>name<\/code><\/strong>: &#34920;&#21333;&#23383;&#27573;&#30340;&#21517;&#31216;&#12290;<\/li>\n<li><strong><code>type<\/code><\/strong>: &#34920;&#21333;&#23383;&#27573;&#30340;&#31867;&#22411;&#65292;&#40664;&#35748;&#20026;<code>TextType<\/code>&#12290;<\/li>\n<li><strong><code>constraints<\/code><\/strong>: &#39564;&#35777;&#32422;&#26463;&#65292;&#29992;&#20110;&#30830;&#20445;&#34920;&#21333;&#25968;&#25454;&#30340;&#26377;&#25928;&#24615;&#12290;<\/li>\n<li><strong><code>mapped<\/code><\/strong>: &#26159;&#21542;&#19982;&#23454;&#20307;&#31867;&#20851;&#32852;&#65292;&#22914;&#26524;&#35774;&#32622;&#20026;<code>false<\/code>&#65292;&#21017;&#19981;&#20250;&#23558;&#34920;&#21333;&#25968;&#25454;&#20445;&#23384;&#21040;&#23454;&#20307;&#31867;&#20013;&#12290;<\/li>\n<\/ul>\n<h3>3. &#31034;&#20363;&#20195;&#30721;<\/h3>\n<p>&#20551;&#35774;&#25105;&#20204;&#26377;&#19968;&#20010;&#31616;&#21333;&#30340;&#29992;&#25143;&#27880;&#20876;&#34920;&#21333;&#65292;&#21253;&#21547;&#29992;&#25143;&#21517;&#21644;&#30005;&#23376;&#37038;&#20214;&#20004;&#20010;&#23383;&#27573;&#12290;&#25105;&#20204;&#23558;&#20351;&#29992;&#19978;&#36848;&#20195;&#30721;&#20316;&#20026;&#22522;&#30784;&#12290;<\/p>\n<h4>1. &#23450;&#20041;&#23454;&#20307;&#31867;<\/h4>\n<pre><code class=\"language-php\">\/\/ src\/Entity\/User.php\nnamespace AppEntity;\n\nuse SymfonyComponentValidatorConstraints as Assert;\n\nclass User\n{\n    private $id;\n    private $username;\n    private $email;\n\n    \/\/ Getters and setters\n}<\/code><\/pre>\n<h4>2. &#21019;&#24314;&#34920;&#21333;&#31867;&#22411;<\/h4>\n<pre><code class=\"language-php\">\/\/ src\/Form\/Type\/UserType.php\nnamespace AppFormType;\n\nuse SymfonyComponentFormAbstractType;\nuse SymfonyComponentFormExtensionCoreTypeTextType;\nuse SymfonyComponentFormExtensionCoreTypeEmailType;\nuse SymfonyComponentOptionsResolverOptionsResolver;\n\nclass UserType extends AbstractType\n{\n    public function buildForm(FormBuilderInterface $builder, array $options)\n    {\n        $builder\n            -&gt;add('username', TextType::class, [\n                'label' =&gt; 'Username',\n                'constraints' =&gt; [\n                    new AssertNotBlank(),\n                    new AssertLength(min: 3),\n                ],\n            ])\n            -&gt;add('email', EmailType::class, [\n                'label' =&gt; 'Email',\n                'constraints' =&gt; [\n                    new AssertNotBlank(),\n                    new AssertEmail(),\n                ],\n            ]);\n    }\n\n    public function configureOptions(OptionsResolver $resolver)\n    {\n        $resolver-&gt;setDefaults([\n            'data_class' =&gt; User::class,\n        ]);\n    }\n}<\/code><\/pre>\n<h4>3. &#21019;&#24314;&#25511;&#21046;&#22120;<\/h4>\n<pre><code class=\"language-php\">\/\/ src\/Controller\/UserController.php\nnamespace AppController;\n\nuse AppEntityUser;\nuse AppFormTypeUserType;\nuse SymfonyBundleFrameworkBundleControllerAbstractController;\nuse SymfonyComponentHttpFoundationRequest;\nuse SymfonyComponentHttpFoundationResponse;\n\nclass UserController extends AbstractController\n{\n    public function register(Request $request): Response\n    {\n        $user = new User();\n        $form = $this-&gt;createForm(UserType::class, $user);\n\n        if ($form-&gt;isSubmitted() &amp;&amp; $form-&gt;isValid()) {\n            \/\/ &#22788;&#29702;&#34920;&#21333;&#25968;&#25454;\n            $entityManager = $this-&gt;getDoctrine()-&gt;getManager();\n            $entityManager-&gt;persist($user);\n            $entityManager-&gt;flush();\n\n            return $this-&gt;redirectToRoute('home');\n        }\n\n        return $this-&gt;render('register.html.twig', [\n            'form' =&gt; $form-&gt;createView(),\n        ]);\n    }\n}<\/code><\/pre>\n<h4>4. &#21019;&#24314;&#35270;&#22270;<\/h4>\n<pre><code class=\"language-twig\">&lt;!-- templates\/register.html.twig --&gt;\n&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n&lt;head&gt;\n    &lt;title&gt;User Registration&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;h1&gt;User Registration&lt;\/h1&gt;\n    {{ form_start(form) }}\n        {{ form_row(form.username) }}\n        {{ form_row(form.email) }}\n        &lt;button type=\"submit\"&gt;Register&lt;\/button&gt;\n    {{ form_end(form) }}\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<p>&#36890;&#36807;&#20197;&#19978;&#27493;&#39588;&#65292;&#20320;&#21487;&#20197;&#25104;&#21151;&#22320;&#22312;Symfony&#30340;&#34920;&#21333;&#32452;&#20214;&#20013;&#23454;&#29616;&#29992;&#25143;&#27880;&#20876;&#21151;&#33021;&#12290;&#24076;&#26395;&#36825;&#31687;&#25351;&#21335;&#23545;&#20320;&#26377;&#25152;&#24110;&#21161;&#65281;<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div><div class=\"wp-block-columns p-0 border is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-columns px-4 py-3 border-bottom has-background is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\" style=\"background:linear-gradient(243deg,rgb(238,238,238) 0%,rgba(58,166,242,0.15) 100%)\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-6c531013 wp-block-group-is-layout-flex\">\r\n<figure class=\"wp-block-image size-thumbnail is-resized is-style-rounded is-style-rounded--2\"><img decoding=\"async\" src=\"https:\/\/www.zhaozhao123.cn\/myitems\/images\/sites16\/2025\/06\/zp-400x300.jpg\" alt=\"&#40657;&#26495;Bug&#35762;&#24072;\" class=\"wp-image-1849\" style=\"object-fit:cover;width:30px;height:30px\"><\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading my-0\" style=\"font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.175), 1rem);\">&#40657;&#26495;Bug&#35762;&#24072;<\/h2>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"wp-block-columns px-xl-5 px-4 py-xl-4 py-3 is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<body><h2>&#27010;&#35272;<\/h2><p>&#24320;&#21457;Web&#24212;&#29992;&#26102;&#65292;&#36890;&#24120;&#38656;&#35201;&#22788;&#29702;&#34920;&#21333;&#12290;&#22312;Symfony&#26694;&#26550;&#20013;&#65292;Form&#32452;&#20214;&#26159;&#19968;&#20010;&#38750;&#24120;&#37325;&#35201;&#30340;&#37096;&#20998;&#65292;&#23427;&#31616;&#21270;&#20102;&#34920;&#21333;&#30340;&#21019;&#24314;&#21644;&#22788;&#29702;&#12290;&#26412;&#25945;&#31243;&#20026;&#24744;&#25552;&#20379;&#20102;&#19968;&#22871;&#23454;&#29992;&#25351;&#21335;&#65292;&#24110;&#21161;&#24744;&#26377;&#25928;&#22320;&#20351;&#29992;Symfony Form&#32452;&#20214;&#12290;<\/p><h2>Symfony Form Component &#8211; &#22522;&#26412;&#27010;&#24565;<\/h2><p>Symfony&#34920;&#21333;&#32452;&#20214;&#26088;&#22312;&#36731;&#26494;&#19988;&#23433;&#20840;&#22320;&#22788;&#29702;&#29992;&#25143;&#36755;&#20837;&#12290;&#23427;&#25552;&#20379;&#20102;&#29983;&#25104;&#34920;&#21333;&#20803;&#32032;&#12289;&#39564;&#35777;&#12289;&#36716;&#25442;&#31561;&#21151;&#33021;&#30340;&#24037;&#20855;&#12290;&#20174;Symfony&#24320;&#22987;&#65292;&#20320;&#24212;&#35813;&#39318;&#20808;&#29087;&#24713;&#19968;&#20123;&#22522;&#26412;&#27010;&#24565;&#12290;<\/p><h3>&#35774;&#32622;&#21644;&#37197;&#32622;<\/h3><p>&#22312;&#35774;&#32622;&#22909;Symfony&#39033;&#30446;&#21518;&#65292;&#38656;&#35201;&#30830;&#20445;Form&#32452;&#20214;&#24050;&#23433;&#35013;&#12290;&#20351;&#29992;&#20197;&#19979;&#21629;&#20196;&#65306;<\/p><pre><code>composer require symfony\/form\n<\/code><\/pre><p>&#35813;&#21629;&#20196;&#20250;&#25289;&#21462;&#34920;&#21333;&#32452;&#20214;&#21450;&#20854;&#25152;&#38656;&#30340;&#25152;&#26377;&#20381;&#36182;&#39033;&#12290;<\/p><h3>&#21019;&#24314;&#19968;&#20010;&#31616;&#21333;&#30340;&#34920;&#21333;<\/h3><p>&#35753;&#25105;&#20204;&#20808;&#21019;&#24314;&#19968;&#20010;&#31616;&#21333;&#30340;&#34920;&#21333;&#12290;&#22312;Symfony&#20013;&#65292;&#34920;&#21333;&#36890;&#24120;&#26159;&#22312;Form&#31867;&#20013;&#26500;&#24314;&#30340;&#12290;&#19979;&#38754;&#26159;&#29983;&#25104;&#34920;&#21333;&#30340;&#27493;&#39588;&#65306;<\/p><pre><code>php bin\/console make:form\n<\/code><\/pre><p>&#35831;&#25353;&#29031;&#25552;&#31034;&#20026;&#24744;&#30340;&#34920;&#21333;&#31867;&#21629;&#21517;&#65288;&#20363;&#22914;&#65292;&#8217;TaskType&#8217;&#65289;&#12290;&#25511;&#21046;&#21488;&#20250;&#29983;&#25104;&#19968;&#20010;&#26032;&#30340;&#34920;&#21333;&#31867;&#65292;&#22312; &#8216;src\/Form&#8217; &#25991;&#20214;&#22841;&#19979;&#12290;<\/p><pre><code>namespace AppForm;\n\nuse SymfonyComponentFormAbstractType;\nuse SymfonyComponentFormFormBuilderInterface;\nuse SymfonyComponentOptionsResolverOptionsResolver;\n\nclass TaskType extends AbstractType\n{\n    public function buildForm(FormBuilderInterface $builder, array $options)\n    {\n        $builder\n            -&gt;add('task', TextType::class)\n            -&gt;add('dueDate', DateType::class);\n    }\n\n    public function configureOptions(OptionsResolver $resolver)\n    {\n        $resolver-&gt;setDefaults([\n            'data_class' =&gt; Task::class,\n        ]);\n    }\n}\n<\/code><\/pre><p>&#35813;&#31867;&#23450;&#20041;&#20102;&#19968;&#20010;&#31616;&#21333;&#30340;&#34920;&#21333;&#65292;&#21253;&#21547;&ldquo;&#20219;&#21153;&rdquo;&#21644;&ldquo;&#25130;&#27490;&#26085;&#26399;&rdquo;&#23383;&#27573;&#12290;<\/p><h3>&#20351;&#29992;&#25511;&#21046;&#22120;&#20013;&#30340;&#34920;&#21333;<\/h3><p>&#35201;&#20351;&#29992;&#36825;&#20010;&#34920;&#21333;&#65292;&#24517;&#39035;&#23558;&#20854;&#38598;&#25104;&#21040;&#25511;&#21046;&#22120;&#21160;&#20316;&#20013;&#65306;<\/p><pre><code>namespace AppController;\n\nuse SymfonyBundleFrameworkBundleControllerAbstractController;\nuse SymfonyComponentHttpFoundationRequest;\nuse AppFormTaskType;\nuse AppEntityTask;\n\nclass TaskController extends AbstractController\n{\n    \/\/ ...\n    public function new(Request $request)\n    {\n        \/\/ creates a task object and initializes some data for this example\n        $task = new Task();\n\n        \/\/ create the form passing the object\n        $form = $this-&gt;createForm(TaskType::class, $task);\n\n        \/\/ handle the request\n        $form-&gt;handleRequest($request);\n\n        \/\/ check if the form is submitted and valid\n        if ($form-&gt;isSubmitted() &amp;&amp; $form-&gt;isValid()) {\n            \/\/ persist the data...\n\n            return $this-&gt;redirectToRoute('task_success');\n        }\n\n        \/\/ render the form\n        return $this-&gt;render('task\/new.html.twig', [\n            'form' =&gt; $form-&gt;createView(),\n        ]);\n    }\n    \/\/...\n}\n<\/code><\/pre><p>&#35813;&#25511;&#21046;&#22120;&#26041;&#27861;&#21019;&#24314;&#26032;&#20219;&#21153;&#65292;&#26500;&#24314;&#34920;&#21333;&#65292;&#22788;&#29702;&#35831;&#27714;&#65292;&#22312;&#25552;&#20132;&#21644;&#39564;&#35777;&#21518;&#22788;&#29702;&#25968;&#25454;&#12290;<\/p><h3>&#22312;&#27169;&#26495;&#20013;&#28210;&#26579;&#34920;&#21333;<\/h3><p>&#20026;&#20102;&#26174;&#31034;&#34920;&#21333;&#65292;&#20320;&#38656;&#35201;&#22312;Twig&#27169;&#26495;&#20013;&#28210;&#26579;&#23427;&#65306;<\/p><pre><code>{% extends 'base.html.twig' %}\n\n{% block body %}\n    {{ form_start(form) }}\n    {{ form_widget(form) }}\n    {{ form_end(form) }}\n{% endblock %}\n<\/code><\/pre><p>&#36825;&#20123;Twig&#20989;&#25968;&#20026;&#34920;&#21333;&#29983;&#25104;HTML&#65292;&#21253;&#25324;&#34920;&#21333;&#26631;&#31614;&#12289;&#34920;&#21333;&#25511;&#20214;&#21644;&#20851;&#38381;&#34920;&#21333;&#26631;&#31614;&#30340;&#20869;&#23481;&#12290;&#24744;&#21487;&#20197;&#36827;&#19968;&#27493;&#23450;&#21046;&#34920;&#21333;&#65292;&#36890;&#36807;&#28210;&#26579;&#27599;&#20010;&#23383;&#27573;&#25110;&#21033;&#29992;&#20869;&#32622;&#30340;Bootstrap&#27169;&#26495;&#26469;&#23454;&#29616;&#12290;<\/p><h3>&#39564;&#35777;<\/h3><p>Form&#32452;&#20214;&#19982;Symfony&#30340;Validator&#32452;&#20214;&#26080;&#32541;&#38598;&#25104;&#12290;&#21487;&#20197;&#22312;&#34920;&#21333;&#31867;&#20013;&#30452;&#25509;&#23450;&#20041;&#39564;&#35777;&#32422;&#26463;&#65292;&#20063;&#21487;&#20197;&#22312;&#23454;&#20307;&#31867;&#20013;&#20351;&#29992;&#27880;&#35299;&#36827;&#34892;&#23450;&#20041;&#12290;<\/p><p>&#22312;&ldquo;&#20219;&#21153;&#31867;&#22411;&rdquo;&#23383;&#27573;&#20013;&#65292;&#25105;&#20204;&#21487;&#20197;&#22312;&ldquo;&#20219;&#21153;&rdquo;&#23383;&#27573;&#20013;&#35774;&#32622;&#20026;&#24517;&#22635;&#65306;<\/p><pre><code>use SymfonyComponentFormExtensionCoreTypeTextType;\nuse SymfonyComponentValidatorConstraintsNotBlank;\n\nclass TaskType extends AbstractType\n{\n    \/\/...\n    public function buildForm(FormBuilderInterface $builder, array $options)\n    {\n        $builder\n            -&gt;add('task', TextType::class, [\n                'constraints' =&gt; new NotBlank(),\n            ])\n            \/\/ ...\n    }\n    \/\/...\n}\n<\/code><\/pre><p>&#36825;&#30830;&#20445;&#22312;&#25552;&#20132;&#34920;&#21333;&#26102;&#65292;&ldquo;&#20219;&#21153;&rdquo;&#23383;&#27573;&#24517;&#39035;&#22635;&#20889;&#12290;<\/p><h2>&#39640;&#32423;&#34920;&#21333;&#20351;&#29992;<\/h2><p>Symfony &#34920;&#21333;&#38750;&#24120;&#28789;&#27963;&#65292;&#21487;&#20197;&#26500;&#24314;&#22797;&#26434;&#30340;&#34920;&#21333;&#32467;&#26500;&#65292;&#22914;&#23884;&#22871;&#34920;&#21333;&#12289;&#38598;&#21512;&#31867;&#22411;&#21644;&#20107;&#20214;&#30417;&#21548;&#22120;&#12290;&#20197;&#19979;&#26159;&#19968;&#20010;&#23884;&#20837;&#38598;&#21512;&#34920;&#21333;&#30340;&#31034;&#20363;&#65306;<\/p><pre><code>use SymfonyComponentFormExtensionCoreTypeCollectionType;\n\nclass TaskType extends AbstractType\n{\n    \/\/...\n    public function buildForm(FormBuilderInterface $builder, array $options)\n    {\n        $builder\n            \/\/ ...\n            -&gt;add('tags', CollectionType::class, [\n                'entry_type' =&gt; TagType::class,\n                'entry_options' =&gt; ['label' =&gt; false],\n                'allow_add' =&gt; true,\n                'allow_delete' =&gt; true,\n            ]);\n    }\n    \/\/...\n}\n<\/code><\/pre><p>&#22312;&#36825;&#31181;&#24773;&#20917;&#19979;&#65292;&ldquo;&#26631;&#31614;&rdquo;&#26159;&#30001;&ldquo;&#26631;&#31614;&#31867;&#22411;&rdquo;&#34920;&#21333;&#32452;&#25104;&#30340;&#38598;&#21512;&#65292;&#29992;&#25143;&#21487;&#20197;&#28155;&#21152;&#25110;&#21024;&#38500;&#36825;&#20123;&#26631;&#31614;&#12290;<\/p><h3>&#27880;&#20876;&#20107;&#20214;&#30417;&#21548;&#22120;<\/h3><p>Symfony&#30340;&#34920;&#21333;&#32452;&#20214;&#20801;&#35768;&#24744;&#30417;&#21548;&#34920;&#21333;&#20107;&#20214;&#24182;&#26681;&#25454;&#26465;&#20214;&#20462;&#25913;&#34920;&#21333;&#12290;&#20197;&#19979;&#26159;&#31034;&#20363;&#20195;&#30721;&#65292;&#28436;&#31034;&#22914;&#20309;&#20026;&#34920;&#21333;&#28155;&#21152;&#20107;&#20214;&#30417;&#21548;&#22120;&#65306;<\/p><pre><code>use SymfonyComponentFormFormEvents;\n\n\/\/ ...\n$builder-&gt;addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {\n    $form = $event-&gt;getForm();\n\n    \/\/ Conditionally add or modify form fields\n    if (\/* some condition *\/) {\n        $form-&gt;add('additionalField', TextType::class);\n    }\n});\n<\/code><\/pre><p>&#35813;&#31034;&#20363;&#22312;&#36816;&#34892;&#26102;&#26681;&#25454;&#26465;&#20214;&#28155;&#21152;&ldquo;&#38468;&#21152;&#23383;&#27573;&rdquo;&#21040;&#34920;&#21333;&#20013;&#12290;<\/p><h2>&#32467;&#35770;&#12290;<\/h2><p>Symfony&#30340;&#34920;&#21333;&#32452;&#20214;&#26159;&#19968;&#20010;&#24378;&#22823;&#30340;&#24037;&#20855;&#12290;&#26080;&#35770;&#26159;&#26500;&#24314;&#31616;&#21333;&#30340;&#36824;&#26159;&#22797;&#26434;&#30340;&#34920;&#21333;&#65292;Symfony&#37117;&#20026;&#20320;&#25552;&#20379;&#20102;&#22810;&#31181;&#21151;&#33021;&#21644;&#38598;&#25104;&#26469;&#39640;&#25928;&#22320;&#21019;&#24314;&#12289;&#22788;&#29702;&#21644;&#31649;&#29702;&#34920;&#21333;&#12290;&#35831;&#22987;&#32456;&#21442;&#32771;Symfony&#23448;&#26041;&#25991;&#26723;&#20013;&#30340;&#34920;&#21333;&#32452;&#20214;&#20197;&#20102;&#35299;&#26368;&#20339;&#23454;&#36341;&#21644;&#26032;&#29305;&#24615;&#12290;<\/p><\/body>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div><div class=\"wp-block-columns p-0 border is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-columns px-4 py-3 border-bottom has-background is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\" style=\"background:linear-gradient(243deg,rgb(238,238,238) 0%,rgba(58,166,242,0.15) 100%)\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-6c531013 wp-block-group-is-layout-flex\">\r\n<figure class=\"wp-block-image size-thumbnail is-resized is-style-rounded is-style-rounded--3\"><img decoding=\"async\" src=\"https:\/\/www.zhaozhao123.cn\/myitems\/images\/sites16\/2025\/06\/xygcfznnzczhsdmwydzhsmzzzmddnq-400x300.jpg\" alt=\"&#38271;&#24037;&#30721;&#22900;1523\" class=\"wp-image-2906\" style=\"object-fit:cover;width:30px;height:30px\"><\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading my-0\" style=\"font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.175), 1rem);\">&#38271;&#24037;&#30721;&#22900;1523<\/h2>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"wp-block-columns px-xl-5 px-4 py-xl-4 py-3 is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<p>&#22312;&#20351;&#29992; Symfony &#30340;&#34920;&#21333;&#32452;&#20214;&#26102;&#65292;&#21487;&#20197;&#36981;&#24490;&#20197;&#19979;&#23454;&#29992;&#25351;&#21335;&#26469;&#30830;&#20445;&#20320;&#30340;&#24212;&#29992;&#31243;&#24207;&#20855;&#26377;&#33391;&#22909;&#30340;&#29992;&#25143;&#20307;&#39564;&#21644;&#21151;&#33021;&#23436;&#25972;&#24615;&#65306;<\/p>\n<ol>\n<li>\n<p><strong>&#20102;&#35299;&#22522;&#26412;&#27010;&#24565;<\/strong>&#65306;<\/p>\n<ul>\n<li><strong>Form Class<\/strong>: &#22312; Symfony &#20013;&#23450;&#20041;&#34920;&#21333;&#31867;&#26159;&#20851;&#38190;&#30340;&#31532;&#19968;&#27493;&#12290;<\/li>\n<li><strong>Model Interface<\/strong>: &#36890;&#24120;&#24773;&#20917;&#19979;&#65292;&#34920;&#21333;&#27169;&#22411;&#65288;Model&#65289;&#19982;&#25968;&#25454;&#34920;&#20851;&#32852;&#65292;&#20363;&#22914; <code>User<\/code> &#34920;&#20013;&#30340;&#29992;&#25143;&#20449;&#24687;&#12290;<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>&#21019;&#24314;&#34920;&#21333;&#31867;<\/strong>&#65306;<\/p>\n<pre><code class=\"language-php\">&lt;?php\n\nnamespace AppForm;\n\nuse SymfonyComponentFormAbstractType;\nuse SymfonyComponentFormExtensionCoreTypeTextType;\nuse SymfonyComponentFormFormBuilderInterface;\nuse SymfonyComponentOptionsResolverOptionsResolver;\n\nclass UserFormType extends AbstractType\n{\n   public function buildForm(FormBuilderInterface $builder, array $options)\n   {\n       $builder\n           -&gt;add('username', TextType::class, [\n               'label' =&gt; 'Username',\n               'attr' =&gt; ['placeholder' =&gt; 'Enter your username'],\n           ])\n           -&gt;add('email', TextType::class, [\n               'label' =&gt; 'Email',\n               'attr' =&gt; ['placeholder' =&gt; 'Enter your email'],\n           ]);\n   }\n\n   public function configureOptions(OptionsResolver $resolver)\n   {\n       $resolver-&gt;setDefaults([\n           'data_class' =&gt; User::class,\n       ]);\n   }\n}<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>&#37197;&#32622;&#34920;&#21333;<\/strong>&#65306;\n&#22312; Symfony &#30340; <code>app\/config\/config.yml<\/code> &#25991;&#20214;&#20013;&#28155;&#21152;&#34920;&#21333;&#31867;&#22411;&#65306;<\/p>\n<pre><code>form:  \n  user_form:\n     type: AppFormUserFormType\n     options:  \n        data_class: AppEntityUser<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>&#39564;&#35777;&#36755;&#20837;<\/strong>&#65306;\n&#20351;&#29992; <code>Validator<\/code> &#27169;&#22359;&#23545;&#34920;&#21333;&#36827;&#34892;&#39564;&#35777;&#65292;&#30830;&#20445;&#25552;&#20132;&#30340;&#25968;&#25454;&#31526;&#21512;&#39044;&#26399;&#65306;<\/p>\n<pre><code class=\"language-php\">\/\/ app\/Form\/UserValidator.php\nnamespace AppValidator;\n\nuse SymfonyComponentValidatorConstraint;\nuse SymfonyComponentValidatorConstraintValidator;\n\nclass UsernameExistsValidator extends ConstraintValidator\n{\n   \/**\n    * @var AppRepositoryUserRepository\n    *\/\n   private $userRepository;\n\n   public function __construct(UserRepository $userRepository)\n   {\n       $this-&gt;userRepository = $userRepository;\n   }\n\n   public function validate($value, Constraint $constraint)\n   {\n       if ($constraint instanceof UsernameExists) {\n           $existingUsers = $this-&gt;userRepository-&gt;findBy(['username' =&gt; $value]);\n           if (count($existingUsers) &gt; 0) {\n               $this-&gt;context-&gt;buildViolation($constraint-&gt;message)-&gt;atPath('username')-&gt;addViolation();\n           }\n       }\n   }\n}<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>&#37096;&#32626;&#34920;&#21333;<\/strong>&#65306;\n&#23558;&#34920;&#21333;&#32452;&#20214;&#38598;&#25104;&#21040;&#20320;&#30340;&#39033;&#30446;&#20013;&#65292;&#24182;&#36890;&#36807; <code>form_builder.yml<\/code> &#37197;&#32622;&#25991;&#20214;&#36827;&#34892;&#27880;&#20876;&#65306;<\/p>\n<pre><code class=\"language-yaml\">form:  \n  user_form: \n      type: AppFormUserFormType\n      properties:  \n          model: AppEntityUser  <\/code><\/pre>\n<\/li>\n<li>\n<p><strong>&#27979;&#35797;&#34920;&#21333;<\/strong>&#65306;\n&#20351;&#29992;&#21333;&#20803;&#27979;&#35797;&#26816;&#26597;&#34920;&#21333;&#22788;&#29702;&#27491;&#30830;&#24615;&#65292;&#20363;&#22914;&#39564;&#35777;&#29305;&#23450;&#23383;&#27573;&#26159;&#21542;&#34987;&#27491;&#30830;&#22635;&#20805;&#65306;<\/p>\n<pre><code class=\"language-php\">\/\/ app\/Tests\/App\/Form\/UserFormTest.php\nnamespace AppTestsAppForm;\n\nuse SymfonyBundleFrameworkBundleTestWebTestCase;\nuse SymfonyComponentHttpFoundationRequest;\nuse SymfonyComponentRoutingGeneratorUrlGeneratorInterface;\nuse SymfonyComponentSecurityHttpAuthenticationAuthenticationUtils;\nuse SymfonyComponentSecurityHttpFirewallFirewallGuard;\n\nfinal class UserFormTest extends WebTestCase\n{\n   protected function setUp(): void\n   {\n       parent::setUp();\n\n       $this-&gt;client = static::createClient([], ['kernel.request' =&gt; new Request()]);\n       $guard = $this-&gt;container-&gt;get(FirewallGuard::class);\n       $auth = $this-&gt;container-&gt;get(AuthenticationUtils::class);\n\n       $this-&gt;client-&gt;request(\n           'POST',\n           '\/users',\n           [],\n           [],\n           [\n               'server' =&gt; [\n                   'HTTP_X_FORWARDED_PROTO' =&gt; 'https',\n                   'REMOTE_ADDR' =&gt; '127.0.0.1'\n               ],\n               'security.token_storage' =&gt; $guard-&gt;getTokenStorage(),\n               'security.authentication_context.request' =&gt; $auth,\n               'kernel.request' =&gt; new Request()\n           ]\n       );\n   }\n\n   public function testCreateUser(): void\n   {\n       $response = $this-&gt;client-&gt;submitForm([], [\n           'form_id' =&gt; 'user_form'\n       ]);\n\n       $this-&gt;assertResponseStatusCodeIs(201);\n   }\n}<\/code><\/pre>\n<\/li>\n<\/ol>\n<p>&#36825;&#20123;&#27493;&#39588;&#26377;&#21161;&#20110;&#20320;&#26377;&#25928;&#22320;&#20351;&#29992; Symfony &#30340;&#34920;&#21333;&#32452;&#20214;&#26469;&#26500;&#24314;&#21644;&#31649;&#29702;&#34920;&#21333;&#25968;&#25454;&#12290;&#26681;&#25454;&#23454;&#38469;&#24212;&#29992;&#38656;&#27714;&#65292;&#21487;&#33021;&#20250;&#26377;&#20854;&#20182;&#38656;&#35201;&#32771;&#34385;&#30340;&#38382;&#39064;&#65292;&#22914;&#34920;&#21333;&#39564;&#35777;&#12289;&#38169;&#35823;&#22788;&#29702;&#31561;&#12290;&#24076;&#26395;&#36825;&#20123;&#24314;&#35758;&#23545;&#20320;&#26377;&#25152;&#24110;&#21161;&#65281;<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Bug&#32534;&#35793;&#29422; &#12298;Symfony&#34920;&#21333;&#32452;&#20214;&#23454;&#29992;&#25351;&#21335;&#12299; &#22312;&#29616;&#20195;Web&#24320;&#21457;&#038;..<\/p>\n","protected":false},"author":1,"featured_media":0,"menu_order":0,"template":"","meta":{"_acf_changed":false},"tags":[],"my1js2nav":[45],"tuisongtax":[],"class_list":["post-1146","my1js","type-my1js","status-publish","hentry","my1js2nav-symfony"],"acf":{"qian_art_seotitle":"","qian_art_seotitle_source":{"label":"SEO\u6807\u9898","type":"text","formatted_value":""},"qian_art_seokws":"","qian_art_seokws_source":{"label":"SEO\u5173\u952e\u8bcd","type":"text","formatted_value":""},"qian_art_stzhong":"","qian_art_stzhong_source":{"label":"\u4e2d | \u77ed\u6807\u9898","type":"text","formatted_value":""}},"_links":{"self":[{"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/my1js\/1146","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/my1js"}],"about":[{"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/types\/my1js"}],"author":[{"embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/users\/1"}],"wp:attachment":[{"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/media?parent=1146"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/tags?post=1146"},{"taxonomy":"my1js2nav","embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/my1js2nav?post=1146"},{"taxonomy":"tuisongtax","embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/tuisongtax?post=1146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}