{"id":1121,"date":"2025-06-12T13:29:29","date_gmt":"2025-06-12T05:29:29","guid":{"rendered":"https:\/\/www.zhaozhao123.cn\/php\/php-application-manual\/symfony\/1121.html"},"modified":"2025-06-12T13:29:29","modified_gmt":"2025-06-12T05:29:29","slug":"%e5%9c%a8-doctrine-%e4%b8%ad%e4%bd%bf%e7%94%a8-symfony-%e9%aa%8c%e8%af%81%e5%99%a8%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\/1121.html","title":{"rendered":"\u5728 Doctrine \u4e2d\u4f7f\u7528 Symfony \u9a8c\u8bc1\u5668\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>&#22312; Doctrine &#20013;&#20351;&#29992; Symfony &#39564;&#35777;&#22120;&#26159;&#19968;&#20010;&#38750;&#24120;&#26377;&#29992;&#30340;&#24037;&#20855;&#65292;&#21487;&#20197;&#24110;&#21161;&#20320;&#22312;&#24212;&#29992;&#31243;&#24207;&#20013;&#36827;&#34892;&#25968;&#25454;&#39564;&#35777;&#12290;&#20197;&#19979;&#26159;&#19968;&#20123;&#23454;&#29992;&#30340;&#25351;&#21335;&#21644;&#31034;&#20363;&#20195;&#30721;&#65292;&#24110;&#21161;&#20320;&#22312; Symfony &#24212;&#29992;&#31243;&#24207;&#20013;&#20351;&#29992; Doctrine &#39564;&#35777;&#22120;&#12290;<\/p>\n<h3>1. &#23433;&#35013; Symfony &#21644; Doctrine<\/h3>\n<p>&#39318;&#20808;&#65292;&#30830;&#20445;&#20320;&#24050;&#32463;&#23433;&#35013;&#20102; Symfony &#21644; Doctrine&#12290;&#22914;&#26524;&#27809;&#26377;&#23433;&#35013;&#65292;&#21487;&#20197;&#20351;&#29992; Composer &#36827;&#34892;&#23433;&#35013;&#65306;<\/p>\n<pre><code class=\"language-bash\">composer create-project symfony\/skeleton my_project --prefer-dist\ncd my_project<\/code><\/pre>\n<p>&#28982;&#21518;&#65292;&#23433;&#35013; Doctrine&#65306;<\/p>\n<pre><code class=\"language-bash\">composer require doctrine\/orm<\/code><\/pre>\n<h3>2. &#21019;&#24314;&#23454;&#20307;&#31867;<\/h3>\n<p>&#21019;&#24314;&#19968;&#20010;&#31616;&#21333;&#30340;&#23454;&#20307;&#31867;&#26469;&#27979;&#35797;&#39564;&#35777;&#22120;&#30340;&#21151;&#33021;&#65306;<\/p>\n<pre><code class=\"language-php\">namespace AppEntity;\n\nuse DoctrineORMMapping as ORM;\nuse SymfonyComponentValidatorConstraints as Assert;\n\n\/**\n * @ORMEntity(repositoryClass=\"AppRepositoryUserRepository\")\n *\/\nclass User\n{\n    \/**\n     * @ORMId\n     * @ORMGeneratedValue(strategy=\"AUTO\")\n     * @ORMColumn(type=\"integer\")\n     *\/\n    private $id;\n\n    \/**\n     * @ORMColumn(type=\"string\", length=255, nullable=false)\n     * @AssertNotBlank(message=\"The username cannot be blank.\")\n     * @AssertLength(min=3, max=20, message=\"Username must be between 3 and 20 characters long.\")\n     *\/\n    private $username;\n\n    \/**\n     * @ORMColumn(type=\"string\", length=60, nullable=true)\n     * @AssertEmail(message=\"Please enter a valid email address.\")\n     *\/\n    private $email;\n\n    \/\/ Getters and Setters\n}<\/code><\/pre>\n<h3>3. &#37197;&#32622;&#39564;&#35777;&#22120;<\/h3>\n<p>&#22312; <code>config\/packages\/doctrine.yaml<\/code> &#25991;&#20214;&#20013;&#37197;&#32622;&#39564;&#35777;&#22120;&#65306;<\/p>\n<pre><code class=\"language-yaml\">doctrine:\n    orm:\n        auto_generate_proxy_classes: true\n        naming_strategy: doctrine.orm.namingStrategy.default\n        mappings:\n            App:\n                type: annotation\n                dir: '%kernel.project_dir%\/src\/Entity'\n                prefix: 'AppEntity'<\/code><\/pre>\n<h3>4. &#20351;&#29992;&#39564;&#35777;&#22120;<\/h3>\n<p>&#22312;&#25511;&#21046;&#22120;&#20013;&#20351;&#29992;&#39564;&#35777;&#22120;&#26469;&#39564;&#35777;&#29992;&#25143;&#36755;&#20837;&#65306;<\/p>\n<pre><code class=\"language-php\">namespace AppController;\n\nuse AppEntityUser;\nuse AppFormUserType;\nuse SymfonyBundleFrameworkBundleControllerAbstractController;\nuse SymfonyComponentHttpFoundationRequest;\nuse SymfonyComponentRoutingAnnotationRoute;\nuse SymfonyComponentValidatorValidatorInterface;\n\nclass UserController extends AbstractController\n{\n    #[Route('\/register', name: 'app_register')]\n    public function register(Request $request, ValidatorInterface $validator): 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            \/\/ Save the user to the database\n            $entityManager = $this-&gt;getDoctrine()-&gt;getManager();\n            $entityManager-&gt;persist($user);\n            $entityManager-&gt;flush();\n\n            return $this-&gt;redirectToRoute('app_home');\n        }\n\n        return $this-&gt;render('user\/register.html.twig', [\n            'form' =&gt; $form-&gt;createView(),\n        ]);\n    }\n}<\/code><\/pre>\n<h3>5. &#21019;&#24314;&#34920;&#21333;&#31867;&#22411;<\/h3>\n<p>&#22312; <code>src\/Form\/UserType.php<\/code> &#25991;&#20214;&#20013;&#21019;&#24314;&#34920;&#21333;&#31867;&#22411;&#65306;<\/p>\n<pre><code class=\"language-php\">namespace AppForm;\n\nuse AppEntityUser;\nuse SymfonyComponentFormAbstractType;\nuse SymfonyComponentFormExtensionCoreTypeTextType;\nuse SymfonyComponentFormExtensionCoreTypeEmailType;\nuse SymfonyComponentFormFormBuilderInterface;\nuse SymfonyComponentOptionsResolverOptionsResolver;\n\nclass UserType extends AbstractType\n{\n    public function buildForm(FormBuilderInterface $builder, array $options): void\n    {\n        $builder\n            -&gt;add('username', TextType::class, [\n                'label' =&gt; 'Username',\n            ])\n            -&gt;add('email', EmailType::class, [\n                'label' =&gt; 'Email',\n            ])\n        ;\n    }\n\n    public function configureOptions(OptionsResolver $resolver): void\n    {\n        $resolver-&gt;setDefaults([\n            'data_class' =&gt; User::class,\n        ]);\n    }\n}<\/code><\/pre>\n<h3>6. &#28210;&#26579;&#34920;&#21333;<\/h3>\n<p>&#22312; <code>templates\/user\/register.html.twig<\/code> &#25991;&#20214;&#20013;&#28210;&#26579;&#34920;&#21333;&#65306;<\/p>\n<pre><code class=\"language-twig\">&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    {{ 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;&#22312; Symfony &#24212;&#29992;&#31243;&#24207;&#20013;&#20351;&#29992; Doctrine &#39564;&#35777;&#22120;&#26469;&#36827;&#34892;&#25968;&#25454;&#39564;&#35777;&#12290;&#36825;&#23558;&#24110;&#21161;&#20320;&#30830;&#20445;&#29992;&#25143;&#25552;&#20379;&#30340;&#25968;&#25454;&#31526;&#21512;&#39044;&#26399;&#30340;&#26684;&#24335;&#21644;&#32422;&#26463;&#26465;&#20214;&#12290;<\/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>&#22312;&#26412;&#25945;&#31243;&#20013;&#65292;&#25105;&#20204;&#23558;&#25506;&#35752;&#22914;&#20309;&#21033;&#29992;Symfony&#30340;&#24378;&#22823;&#39564;&#35777;&#31995;&#32479;&#19982;Doctrine ORM&#23454;&#20307;&#32467;&#21512;&#20351;&#29992;&#12290;&#39564;&#35777;&#26159;&#20219;&#20309;&#24212;&#29992;&#31243;&#24207;&#20013;&#30340;&#20851;&#38190;&#32452;&#25104;&#37096;&#20998;&#65292;&#30830;&#20445;&#25968;&#25454;&#36755;&#20837;&#31526;&#21512;&#39044;&#26399;&#26684;&#24335;&#65292;&#22312;&#22788;&#29702;&#25110;&#20445;&#23384;&#21040;&#25968;&#25454;&#24211;&#20043;&#21069;&#36827;&#34892;&#12290;&#22312;Symfony&#39033;&#30446;&#20013;&#65292;&#39564;&#35777;&#22120;&#22312;&#23454;&#29616;&#36825;&#19968;&#30446;&#26631;&#26041;&#38754;&#21457;&#25381;&#30528;&#37325;&#35201;&#20316;&#29992;&#12290;<\/p><h3>&#20171;&#32461;Symfony&#39564;&#35777;&#22120;<\/h3><p>Symfony &#25552;&#20379;&#20102;&#19968;&#20010;&#39564;&#35777;&#32452;&#20214;&#65292;&#20801;&#35768;&#20320;&#22312;&#25552;&#20132;&#25968;&#25454;&#25110;&#22312;&#25968;&#25454;&#24211;&#20445;&#23384;&#25968;&#25454;&#20043;&#21069;&#24212;&#29992;&#39564;&#35777;&#35268;&#21017;&#12290;&#23427;&#21253;&#25324;&#19968;&#31995;&#21015;&#20869;&#32622;&#30340;&#32422;&#26463;&#39564;&#35777;&#22120;&#65292;&#24182;&#19988;&#21487;&#20197;&#21019;&#24314;&#33258;&#23450;&#20041;&#30340;&#39564;&#35777;&#22120;&#26469;&#28385;&#36275;&#22797;&#26434;&#30340;&#19994;&#21153;&#35268;&#21017;&#12290;<\/p><h3>&#35774;&#32622; Symfony &#19982; Doctrine &#30340;&#27493;&#39588;&#12290;<\/h3><p>&#22312;&#20351;&#29992;Doctrine&#30340;&#39564;&#35777;&#22120;&#20043;&#21069;&#65292;&#35831;&#30830;&#20445;&#24050;&#23433;&#35013;&#21644;&#37197;&#32622;&#20102;Symfony&#21644;Doctrine&#39033;&#30446;&#12290;&#22914;&#26524;&#27809;&#26377;&#65292;&#21487;&#20197;&#21442;&#32771;Symfony&#32593;&#31449;&#19978;&#30340;&#23433;&#35013;&#25351;&#21335;&#26469;&#21019;&#24314;&#19968;&#20010;&#25903;&#25345;Doctrine&#30340;&#26032;Symfony&#39033;&#30446;&#12290;<\/p><h2>&#22522;&#26412;&#23454;&#20307;&#39564;&#35777;<\/h2><p>&#35753;&#25105;&#20204;&#20174;&#19968;&#20010;&#22522;&#26412;&#30340;&#31034;&#20363;&#24320;&#22987;&#65292;&#23637;&#31034;&#22914;&#20309;&#23545;&#29992;&#25143;&#23454;&#20307;&#36827;&#34892;&#39564;&#35777;&#12290;&#24744;&#23558;&#22312;PHP&#23454;&#20307;&#31867;&#20013;&#20351;&#29992;&#27880;&#35299;&#30452;&#25509;&#23450;&#20041;&#35268;&#21017;&#65306;<\/p><pre><code>&lt;?php\n\nnamespace AppEntity;\n\nuse DoctrineORMMapping as ORM;\nuse SymfonyComponentValidatorConstraints as Assert;\n\n\/**\n * @ORMEntity\n *\/\nclass User\n{\n    \/**\n     * @ORMId\n     * @ORMGeneratedValue\n     * @ORMColumn(type=\"integer\")\n     *\/\n    private $id;\n\n    \/**\n     * @AssertNotBlank\n     * @ORMColumn(type=\"string\", length=50)\n     *\/\n    private $username;\n\n    \/\/ ... more properties and methods ...\n}\n<\/code><\/pre><h2>&#39564;&#35777;&#32452;<\/h2><p>&#39564;&#35777;&#32452;&#20801;&#35768;&#24744;&#20026;&#19981;&#21516;&#30340;&#39564;&#35777;&#22330;&#26223;&#24212;&#29992;&#19981;&#21516;&#30340;&#39564;&#35777;&#26465;&#20214;&#65292;&#20174;&#32780;&#25552;&#20379;&#19968;&#31181;&#22312;&#29305;&#23450;&#26465;&#20214;&#19979;&#39564;&#35777;&#32422;&#26463;&#30340;&#26041;&#27861;&#12290;&#20363;&#22914;&#65292;&#22312;&#21019;&#24314;&#26032;&#29992;&#25143;&#26102;&#65292;&#21487;&#33021;&#38656;&#35201;&#24378;&#23494;&#30721;&#65292;&#20294;&#22312;&#26356;&#26032;&#29992;&#25143;&#20449;&#24687;&#26102;&#65292;&#21487;&#33021;&#19981;&#38656;&#35201;&#26356;&#25913;&#23494;&#30721;&#12290;<\/p><pre><code>&lt;?php\n\n\/\/ Entity definition continues...\n\n\/**\n * @AssertNotBlank(groups={\"Registration\"})\n * @AssertLength(min=8, groups={\"Registration\"})\n * @ORMColumn(type=\"string\")\n *\/\nprivate $password;\n\n\/\/ When validating, specify the group\n$violations = $validator-&gt;validate($user, null, ['Registration']);\n<\/code><\/pre><h2>&#20351;&#29992;&#22238;&#35843;&#32422;&#26463;<\/h2><p>&#23545;&#20110;&#26356;&#22797;&#26434;&#30340;&#39564;&#35777;&#38656;&#27714;&#65292;&#21487;&#20197;&#20351;&#29992;&#22238;&#35843;&#32422;&#26463;&#12290;&#36825;&#20123;&#20801;&#35768;&#20320;&#22312;&#23454;&#20307;&#31867;&#20869;&#37096;&#23450;&#20041;&#33258;&#23450;&#20041;&#36923;&#36753;&#65306;<\/p><pre><code>&lt;?php\n\n\/\/ Entity definition continues...\n\nuse SymfonyComponentValidatorContextExecutionContextInterface;\n\n\/**\n * @AssertCallback\n *\/\npublic function validate(ExecutionContextInterface $context, $payload)\n{\n    if (!preg_match('\/^d+$\/', $this-&gt;username)){\n        $context-&gt;buildViolation('Your username cannot contain non-numeric characters.')\n            -&gt;atPath('username')\n            -&gt;addViolation();\n    }\n}\n<\/code><\/pre><h2>&#39564;&#35777;&#38598;&#21512;<\/h2><p>&#22914;&#26524;&#23454;&#20307;&#19982;&#38598;&#21512;&#30456;&#20851;&#65292;&#20351;&#29992; @AssertValid &#27880;&#35299;&#21487;&#20197;&#30830;&#20445;&#38598;&#21512;&#20013;&#30340;&#27599;&#20010;&#39033;&#30446;&#37117;&#36827;&#34892;&#39564;&#35777;&#65306;<\/p><pre><code>&lt;?php\n\n\/\/ Entity definition continues...\n\n\/**\n * @ORMOneToMany(targetEntity=\"Post\", mappedBy=\"author\")\n * @AssertValid\n *\/\nprivate $posts;\n<\/code><\/pre><h2>&#22312; YAML &#25110; XML &#20013;&#37325;&#20889;&#39564;&#35777;&#32422;&#26463;&#12290;<\/h2><p>&#26377;&#26102;&#65292;&#23450;&#20041;&#39564;&#35777;&#35268;&#21017;&#22312;&#23454;&#20307;&#31867;&#20043;&#22806;&#26159;&#26377;&#30410;&#30340;&#65292;&#20197;&#20445;&#25345;&#20195;&#30721;&#25972;&#27905;&#25110;&#20801;&#35768;&#21160;&#24577;&#20462;&#25913;&#32422;&#26463;&#32780;&#19981;&#20462;&#25913;&#20195;&#30721;&#12290;Symfony&#25903;&#25345;&#22312;YAML&#25110;XML&#25991;&#20214;&#20013;&#23450;&#20041;&#39564;&#35777;&#32422;&#26463;&#12290;<\/p><pre><code># config\/validator\/validation.yaml\nAppEntityUser:\n    properties:\n        username:\n            - NotBlank: ~\n            - Length:\n                min: 4\n                max: 48\n            ... # other constraints\n<\/code><\/pre><h2>&#22788;&#29702;&#39564;&#35777;&#38169;&#35823;<\/h2><p>&#22312;&#25191;&#34892;&#39564;&#35777;&#26102;&#65292;&#22914;&#26524;&#23384;&#22312;&#36829;&#35268;&#24773;&#20917;&#65292;Symfony&#30340;Validator&#20250;&#36820;&#22238;&#19968;&#20010;&#38169;&#35823;&#21015;&#34920;&#12290;&#20320;&#38656;&#35201;&#22312;&#25511;&#21046;&#22120;&#20869;&#22949;&#21892;&#22788;&#29702;&#36825;&#20123;&#38169;&#35823;&#65306;<\/p><pre><code>&lt;?php\n\n\/\/ Inside controller action...\n\nuse SymfonyComponentHttpFoundationResponse;\nuse SymfonyComponentValidatorValidatorValidatorInterface;\n\npublic function createUser(Request $request, ValidatorInterface $validator)\n{\n    $user = new User();\n    \/\/ ... populate $user with data from $request ...\n\n    $errors = $validator-&gt;validate($user);\n    if (count($errors) &gt; 0) {\n        return new Response((string) $errors, 400);\n    }\n\n    \/\/ ... save $user to the database ...\n}\n<\/code><\/pre><h2>&#19982;Symfony Forms&#30340;&#38598;&#25104;<\/h2><p>&#22312;&#20351;&#29992;Symfony Forms&#26102;&#65292;&#39564;&#35777;&#21487;&#20197;&#22312;&#34920;&#21333;&#25552;&#20132;&#26102;&#33258;&#21160;&#24212;&#29992;&#12290;&#21482;&#38656;&#23450;&#20041;&#20320;&#30340;&#34920;&#21333;&#31867;&#22411;&#24182;&#35843;&#29992;buildForm&#26041;&#27861;&#65292;&#28982;&#21518;&#23558;&#20854;&#19982;&#23454;&#20307;&#20851;&#32852;&#21363;&#21487;&#65306;<\/p><pre><code>&lt;?php\n\n\/\/ Inside Form Type class...\n\npublic function buildForm(FormBuilderInterface $builder, array $options)\n{\n    $builder-&gt;add('username', TextType::class);\n    \/\/ ... add other fields ...\n}\n\n\/\/ Inside controller...\n\n$form = $this-&gt;createForm(UserType::class, $user);\n$form-&gt;handleRequest($request);\nif ($form-&gt;isSubmitted() &amp;&amp; $form-&gt;isValid()) {\n    \/\/ ... save the user ...\n}\n<\/code><\/pre><h2>&#32467;&#35770;&#12290;<\/h2><p>Symfony&#30340;&#39564;&#35777;&#32452;&#20214;&#19982;Doctrine ORM&#32467;&#21512;&#20351;&#29992;&#65292;&#25552;&#20379;&#20102;&#19968;&#22871;&#24378;&#22823;&#30340;&#19988;&#28789;&#27963;&#30340;&#25968;&#25454;&#23436;&#25972;&#24615;&#20445;&#38556;&#31995;&#32479;&#12290;&#36890;&#36807;&#29702;&#35299;&#21644;&#21033;&#29992;&#25552;&#20379;&#30340;&#21508;&#31181;&#39564;&#35777;&#25216;&#26415;&#65292;&#24744;&#20026;&#24744;&#30340;Symfony&#24212;&#29992;&#31243;&#24207;&#37197;&#22791;&#20102;&#26356;&#24378;&#30340;&#25968;&#25454;&#39564;&#35777;&#26426;&#21046;&#65292;&#24182;&#33021;&#22815;&#36731;&#26494;&#31649;&#29702;&#21644;&#23450;&#21046;&#20197;&#28385;&#36275;&#22810;&#26679;&#21270;&#30340;&#38656;&#27714;&#12290;<\/p><p>&#35831;&#35760;&#20303;&#65292;&#36981;&#24490;&#26368;&#20339;&#23454;&#36341;&#33267;&#20851;&#37325;&#35201;&#65292;&#21253;&#25324;&#36991;&#20813;&#22312;&#23454;&#20307;&#20013;&#20351;&#29992;&#36923;&#36753;&#12289;&#20998;&#31163;&#20851;&#27880;&#28857;&#20197;&#21450;&#30041;&#24847;&#22797;&#26434;&#39564;&#35777;&#23545;&#24615;&#33021;&#30340;&#24433;&#21709;&#12290;&#26377;&#20102;&#36825;&#20221;&#23454;&#29992;&#25351;&#21335;&#65292;&#24744;&#24050;&#32463;&#22312;&#25484;&#25569;&#22522;&#20110;Doctrine&#30340;Symfony&#39564;&#35777;&#26041;&#38754;&#21462;&#24471;&#20102;&#26174;&#33879;&#36827;&#23637;&#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; Doctrine &#21644; Symfony &#26500;&#24314;&#20225;&#19994;&#32423;&#24212;&#29992;&#26102;&#65292;&#39564;&#35777;&#22120;&#26159;&#30830;&#20445;&#25968;&#25454;&#27491;&#30830;&#24615;&#30340;&#20851;&#38190;&#32452;&#20214;&#12290;&#26412;&#25351;&#21335;&#23558;&#24341;&#23548;&#24744;&#20102;&#35299;&#22914;&#20309;&#22312; Doctrine &#20013;&#20351;&#29992; Symfony &#39564;&#35777;&#22120;&#12290;<\/p>\n<h3>1. &#23433;&#35013; Symfony &#39564;&#35777;&#22120;<\/h3>\n<p>&#39318;&#20808;&#65292;&#30830;&#20445;&#24744;&#30340;&#39033;&#30446;&#24050;&#23433;&#35013;&#20102; Symfony &#30340;&#23433;&#20840;&#24037;&#20855;&#21253;&#65288;&#20363;&#22914; <code>symfony\/security<\/code>&#65289;&#12290;&#22914;&#26524;&#27809;&#26377;&#65292;&#35831;&#36816;&#34892;&#20197;&#19979;&#21629;&#20196;&#26469;&#23433;&#35013;&#65306;<\/p>\n<pre><code class=\"language-bash\">composer require symfony\/security-bundle<\/code><\/pre>\n<p>&#28982;&#21518;&#65292;&#36890;&#36807; Composer &#23433;&#35013; Symfony &#39564;&#35777;&#22120;&#65306;<\/p>\n<pre><code class=\"language-bash\">composer require doctrine\/orm\ncomposer require doctrine\/doctrine-bundle\ncomposer require symfony\/security-bundle<\/code><\/pre>\n<h3>2. &#23548;&#20837; Doctrine &#21644; Symfony &#39564;&#35777;&#22120;<\/h3>\n<p>&#22312;&#24744;&#30340;&#24212;&#29992;&#31243;&#24207;&#30340; <code>config\/packages\/doctrine.yaml<\/code> &#25991;&#20214;&#20013;&#65292;&#28155;&#21152;&#20197;&#19979;&#37197;&#32622;&#20197;&#21551;&#29992; Doctrine ORM &#21644; Symfony &#39564;&#35777;&#22120;&#65306;<\/p>\n<pre><code class=\"language-yaml\">doctrine:\n    orm:\n        auto_generate_proxy_classes: \"%kernel.debug%\"\n        mapping_types: true\n        entity_managers:\n            default:\n                entity_factories:\n                    User: DoctrineORMMappingEntityManagerFactoryUserManagerFactory\n                    Product: DoctrineORMMappingEntityManagerFactoryProductManagerFactory\n\nsecurity:\n    providers:\n        - { class: 'SymfonyBundleSecurityBundleDependencyInjectionSecurityProvider', name: 'security' }<\/code><\/pre>\n<p>&#36825;&#37324;&#65292;&#25105;&#20204;&#21019;&#24314;&#20102;&#19968;&#20010;&#21517;&#20026; <code>UserManagerFactory<\/code> &#21644; <code>ProductManagerFactory<\/code> &#30340;&#33258;&#23450;&#20041;&#23454;&#20307;&#24037;&#21378;&#65292;&#29992;&#20110;&#29983;&#25104;&#29992;&#25143;&#21644;&#20135;&#21697;&#27169;&#22411;&#12290;<\/p>\n<h3>3. &#35774;&#32622; Symfony &#39564;&#35777;&#22120;<\/h3>\n<p>&#20026;&#20102;&#20351;&#29992; Symfony &#39564;&#35777;&#22120;&#65292;&#25105;&#20204;&#38656;&#35201;&#20026;&#27599;&#20010;&#38656;&#35201;&#39564;&#35777;&#30340;&#25968;&#25454;&#31867;&#22411;&#35774;&#32622;&#39564;&#35777;&#35268;&#21017;&#12290;&#20026;&#27492;&#65292;&#25105;&#20204;&#23558;&#20462;&#25913;&#25968;&#25454;&#24211;&#36801;&#31227;&#25991;&#20214;&#65292;&#20026;&#29992;&#25143;&#34920;&#28155;&#21152;&#39564;&#35777;&#23383;&#27573;&#12290;<\/p>\n<p>&#25171;&#24320; <code>\/src\/Migrations\/2022_07_04_160849_create_users_table.php<\/code> &#25991;&#20214;&#65292;&#24182;&#23558;&#20197;&#19979;&#20195;&#30721;&#25554;&#20837;&#21040;&#20854;&#20013;&#65306;<\/p>\n<pre><code class=\"language-php\">use DoctrineDBALSchemaSchema;\nuse DoctrineMigrationsAbstractMigration;\n\nclass CreateUsersTable extends AbstractMigration\n{\n    public function up(Schema $schema)\n    {\n        \/\/ Add the following lines to your migration file for each type of validation you want to implement.\n        $this-&gt;addSql('ALTER TABLE user ADD constraint validation_user CHECK (username IS NOT NULL)');\n        $this-&gt;addSql('ALTER TABLE product ADD constraint validation_product CHECK (name IS NOT NULL)');\n    }\n\n    public function down()\n    {\n        \/\/ You can remove these lines if you don't want to change the behavior of your migrations.\n    }\n}<\/code><\/pre>\n<p>&#29616;&#22312;&#65292;&#24744;&#21487;&#20197;&#26681;&#25454;&#38656;&#35201;&#28155;&#21152;&#26356;&#22810;&#31867;&#22411;&#30340;&#39564;&#35777;&#35268;&#21017;&#12290;<\/p>\n<h3>4. &#20351;&#29992; Symfony &#39564;&#35777;&#22120;&#36827;&#34892;&#39564;&#35777;<\/h3>\n<p>&#22312;&#25511;&#21046;&#22120;&#20013;&#65292;&#24744;&#21487;&#20197;&#20351;&#29992; Symfony &#39564;&#35777;&#22120;&#23545;&#35831;&#27714;&#21442;&#25968;&#36827;&#34892;&#39564;&#35777;&#12290;&#20363;&#22914;&#65292;&#20551;&#35774;&#24744;&#26377;&#19968;&#20010;&#21517;&#20026; <code>ProductController<\/code> &#30340;&#25511;&#21046;&#22120;&#65292;&#23427;&#22788;&#29702;&#19982;&#20135;&#21697;&#30456;&#20851;&#30340;&#25805;&#20316;&#65306;<\/p>\n<pre><code class=\"language-php\">namespace AppController;\n\nuse AppEntityProduct;\nuse SymfonyComponentHttpFoundationRequest;\nuse SymfonyComponentHttpFoundationResponse;\nuse SymfonyComponentRoutingAnnotationRoute;\nuse SymfonyComponentValidatorConstraints as Assert;\nuse SymfonyBundleFrameworkBundleControllerAbstractController;\n\n\/**\n * @Route(\"\/products\")\n *\/\nclass ProductController extends AbstractController\n{\n    \/**\n     * @Route(\"\/\", name=\"product_list\", methods={\"GET\"})\n     *\/\n    public function listAction(Request $request): Response\n    {\n        $em = $this-&gt;getDoctrine()-&gt;getManager();\n        $queryBuilder = $em-&gt;createQueryBuilder();\n\n        \/\/ &#20351;&#29992; Symfony &#39564;&#35777;&#22120;&#39564;&#35777;&#26597;&#35810;&#26465;&#20214;\n        $queryBuilder\n            -&gt;select('COUNT(p.id)')\n            -&gt;from(Product::class, 'p')\n            -&gt;where($queryBuilder-&gt;expr()-&gt;andX(\n                $queryBuilder-&gt;expr()-&gt;eq('p.name', ':name'),\n                $queryBuilder-&gt;expr()-&gt;isNull('p.description')\n            ))\n            -&gt;setParameter(':name', $request-&gt;get('search'));\n\n        return $this-&gt;json($queryBuilder-&gt;getQuery()-&gt;getScalarResult());\n    }\n}<\/code><\/pre>\n<h3>&#32467;&#35770;<\/h3>\n<p>&#36890;&#36807;&#20197;&#19978;&#27493;&#39588;&#65292;&#24744;&#24050;&#32463;&#25104;&#21151;&#22320;&#22312; Doctrine &#21644; Symfony &#24212;&#29992;&#31243;&#24207;&#20013;&#35774;&#32622;&#20102;&#22522;&#26412;&#30340;&#39564;&#35777;&#26426;&#21046;&#12290;&#36825;&#21482;&#26159;&#19968;&#20010;&#22522;&#30784;&#26694;&#26550;&#65292;&#24744;&#21487;&#20197;&#26681;&#25454;&#38656;&#35201;&#25193;&#23637;&#27492;&#39564;&#35777;&#21151;&#33021;&#65292;&#27604;&#22914;&#28155;&#21152;&#39069;&#22806;&#30340;&#39564;&#35777;&#35268;&#21017;&#12289;&#26085;&#24535;&#35760;&#24405;&#31561;&#12290;&#24076;&#26395;&#36825;&#20010;&#25351;&#21335;&#33021;&#24110;&#21161;&#24744;&#26500;&#24314;&#26356;&#20581;&#22766;&#30340;&#20225;&#19994;&#32423;&#24212;&#29992;&#31243;&#24207;&#65281;<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Bug&#32534;&#35793;&#29422; &#22312; Doctrine &#20013;&#20351;&#29992; Symfony &#39564;&#35777;&#22120;&#26159;&#19968;&#20010;&#38750;&#24120;&#26377;&#29992;&#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-1121","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\/1121","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=1121"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/tags?post=1121"},{"taxonomy":"my1js2nav","embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/my1js2nav?post=1121"},{"taxonomy":"tuisongtax","embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/tuisongtax?post=1121"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}