我试图通过 Symfony 的 Form 组件来持久化一个对象。它不工作。
提交表单时,Symfony 将我重定向到实际表单,之前提交的数据使用 GET 方法出现在 url 中。在 Profiler 中,我可以观察到“没有 POST 参数”。
控制器:
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\Quest;
use AppBundle\Form\QuestType;
class QuestController extends Controller
{
\\...
/**
* @Route("/admin/quest/add", name="quest_add")
*/
public function addAction(Request $request)
{
$quest = new Quest();
$form = $this->createForm(QuestType::class, $quest);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($quest);
$em->flush();
return $this->redirectToRoute('quest_view');
}
return $this->render('admin/quest/add.html.twig', array(
'form' => $form->createView(),
));
}
}
类型:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
class QuestType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('questName', TextType::class)
->add('questCost', IntegerType::class)
->add('nbEnigma', IntegerType::class)
->add('dateStart', DateTimeType::class)
->add('dateEnd', DateTimeType::class)
->add('rewardFinish', IntegerType::class)
->add('rewardFurther', IntegerType::class)
->add('speech', TextareaType::class)
;
}
\\...
}
风景:
/* ... */
<div class="well">
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_row(form.questName) }}
/* ... */
<input type="submit" value="Create" method="post" class="btn btn-default pull-right" />
{{ form_end(form) }}
</div>
/* ... */
请注意,我暂时不使用验证。
我使用的实体没问题,对应的表已经通过 Symfony 控制台在我的 PostgreSQL 数据库中创建,parameters.yml 的配置也可以。如果需要,我可以发布这些元素。
那么可能出现什么问题呢?这是我的 Wamp 安装或配置中的问题吗,例如 Apache 问题?事实是我不知道问题出在哪里。
请注意,我完全是网络开发的初学者。我实际上尝试学习 PHP 以及 Symfony2。
编辑以下评论
1) 生成的 HTML 显示 Twig 渲染生成的表单将表单的方法设置为 "POST" :
<form name="quest" method="post">
2)在with@Method({"GET", "POST"})
下添加并没有改变任何东西。@Route
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
3.1)关于我的环境的信息:
- Wampserver 2.5 (32 位 & PHP 5.5.12, Apache 2.4.9 )
- PostgreSQL 9.3.2
- Symfony 2.8.1,使用标准版 + FOSUserBundle ~2.0@dev
- 使用 Doctrine2
- 在
/admin
开发环境app_dev.php
(
3.2)在我相同的环境中,我复制了 3 个不同的在线教程(来自 Symfony 书籍、来自 openclassrooms.com 和来自 dynamic-mess.com)中显示的各种形式,并且都以相同的方式结束。
4)以防万一,我只是去重新启动项目,通过重新安装 Symfony,具有相同的版本和相同的配置,具有相同的 Wampserver 和 PostgreSQL。我只是留意防止错过一些步骤。它仍然不起作用。
5)在我的环境中测试基本 HTML 表单: 使用没有类的表单(没有实体)
控制器:
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\TextType;
class QuestController extends Controller
{
// ...
/**
* @Route("/admin/test/add", name="test")
*/
public function testAction(Request $request)
{
$defaultData = array('message' => 'Type your message here');
$form = $this->createFormBuilder($defaultData)
->add('nametest', TextType::class)
->getForm();
$form->handleRequest($request);
if ($form->isValid()) {
$data = $form->getData();
}
return $this->render('admin/test.html.twig', array(
'form' => $form->createView(),
));
}
}
风景 :
/* ... */
<div class="well">
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_row(form.nametest) }}
<input type="submit" value="Create" method="post" class="btn btn-default pull-right" />
{{ app.request }}
{{ form_end(form) }}
</div>
/* ... */
对于这个测试,我使用了 Twig 全局模板变量{{ app.request }}
。
在点击提交按钮之前,页面会显示以下信息:
GET /gowinquest/web/app_dev.php/admin/test/add HTTP/1.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3 Cache-Control: max-age=0 Connection: keep-alive Cookie: __utma=111872281.2124856035.1451232730.1452442012.1452447222.32; __utmz=111872281.1451232730.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=111872281; PPA_ID=not8odr8dlslv6eoo25l2llai6; webfx-tree-cookie-persistence=wfxt-14+wfxt-36+wfxt-20+wfxt-4+wfxt-16+wfxt-18+wfxt-6; PHPSESSID=h94nvh0nn315po8np66httkv56; __utmb=111872281.0.10.1452447222 Host: localhost User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0 X-Php-Ob-Level: 1
之后,生成的页面会丢弃这些信息:
GET /gowinquest/web/app_dev.php/admin/test/add?form%5Bnametest%5D=blablabla&form%5B_token%5D=pzhE6hrzsNf3EYbHJLmEXf0miAh4J5jeOH_ccrmlmW4 HTTP/1.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3 Connection: keep-alive Cookie: __utma=111872281.2124856035.1451232730.1452442012.1452447222.32; __utmz=111872281.1451232730.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=111872281; PPA_ID=not8odr8dlslv6eoo25l2llai6; webfx-tree-cookie-persistence=wfxt-14+wfxt-36+wfxt-20+wfxt-4+wfxt-16+wfxt-18+wfxt-6; PHPSESSID=h94nvh0nn315po8np66httkv56; __utmb=111872281.0.10.1452447222 Host: localhost Referer: http://localhost/gowinquest/web/app_dev.php/admin/test/add User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0 X-Php-Ob-Level: 1
6)我在我的实体上尝试了 Symfony 的 CRUD 控制器和模板生成器,它工作正常!我的数据是通过 POST 发送的,并已在数据库中注册。
但这对我来说仍然是一个巨大的谜团,因为在 Controller 和 Symfony 的 Form 中生成的方法与我之前手动尝试的方法相同......
CRUD 生成器使用@Method({"GET", "POST"})
,这是我在最初的代码中观察到的唯一区别。但这很奇怪,因为我@Method
之前也自己尝试过注释,但并没有改变任何东西(见我的第二次编辑)......
尽管如此,我还是 PHP 和 Symfony 的初学者,一个全新的新手,所以肯定有一些明显的东西我错过了......但是什么?此刻我没有任何想法。欢迎解释,如果有人有线索?我必须弄清楚那个谜的关键。
7) 这是 Symfony2.8 在app/logs/dev.log
文件中默认提供的日志,从我最初显示表单到重定向请求:
[2016-01-11 16:02:38] request.INFO: Matched route "_wdt". {"route_parameters":{"_controller":"web_profiler.controller.profiler:toolbarAction","token":"e945fe","_route":"_wdt"},"request_uri":"http://localhost/gowinquest/web/app_dev.php/_wdt/e945fe"} []
[2016-01-11 16:03:16] request.INFO: Matched route "quest_add". {"route_parameters":{"_controller":"AppBundle\\Controller\\QuestController::addAction","_route":"quest_add"},"request_uri":"http://localhost/gowinquest/web/app_dev.php/admin/quest/add?quest%5B_token%5D=74fPFHnb4NPKfAotccGEE9T4EDCUhaEHY4w-hqViwUw&quest%5BdateEnd%5D%5Bdate%5D%5Bday%5D=1&quest%5BdateEnd%5D%5Bdate%5D%5Bmonth%5D=1&quest%5BdateEnd%5D%5Bdate%5D%5Byear%5D=2011&quest%5BdateEnd%5D%5Btime%5D%5Bhour%5D=0&quest%5BdateEnd%5D%5Btime%5D%5Bminute%5D=0&quest%5BdateStart%5D%5Bdate%5D%5Bday%5D=1&quest%5BdateStart%5D%5Bdate%5D%5Bmonth%5D=1&quest%5BdateStart%5D%5Bdate%5D%5Byear%5D=2011&quest%5BdateStart%5D%5Btime%5D%5Bhour%5D=0&quest%5BdateStart%5D%5Btime%5D%5Bminute%5D=0&quest%5BnbEnigma%5D=1&quest%5BquestCost%5D=1&quest%5BquestName%5D=Test4&quest%5BrewardFinish%5D=1&quest%5BrewardFurther%5D=1&quest%5Bspeech%5D=test4speech"} []
[2016-01-11 16:03:16] security.DEBUG: Read existing security token from the session. {"key":"_security_main"} []
[2016-01-11 16:03:16] doctrine.DEBUG: SELECT t0.username AS username_1, t0.username_canonical AS username_canonical_2, t0.email AS email_3, t0.email_canonical AS email_canonical_4, t0.enabled AS enabled_5, t0.salt AS salt_6, t0.password AS password_7, t0.last_login AS last_login_8, t0.locked AS locked_9, t0.expired AS expired_10, t0.expires_at AS expires_at_11, t0.confirmation_token AS confirmation_token_12, t0.password_requested_at AS password_requested_at_13, t0.roles AS roles_14, t0.credentials_expired AS credentials_expired_15, t0.credentials_expire_at AS credentials_expire_at_16, t0.id AS id_17 FROM fos_user t0 WHERE t0.id = ? LIMIT 1 [1] []
[2016-01-11 16:03:16] security.DEBUG: User was reloaded from a user provider. {"username":"admin","provider":"FOS\\UserBundle\\Security\\EmailUserProvider"} []
[2016-01-11 16:03:17] security.DEBUG: Stored the security token in the session. {"key":"_security_main"} []
[2016-01-11 16:03:18] request.INFO: Matched route "_wdt". {"route_parameters":{"_controller":"web_profiler.controller.profiler:toolbarAction","token":"83737b","_route":"_wdt"},"request_uri":"http://localhost/gowinquest/web/app_dev.php/_wdt/83737b"} []
至于 Profiler(默认配置),仅此而已:
200 ::1 GET http://localhost/gowinquest/web/app_dev.php/admin/quest/add?quest%5B_token%5D=74fPFHnb4NPKfAotccGEE9T4EDCUhaEHY4w-hqViwUw&quest%5BdateEnd%5D%5Bdate%5D%5Bday%5D=1&quest%5BdateEnd%5D%5Bdate%5D%5Bmonth%5D=1&quest%5BdateEnd%5D%5Bdate%5D%5Byear%5D=2011&quest%5BdateEnd%5D%5Btime%5D%5Bhour%5D=0&quest%5BdateEnd%5D%5Btime%5D%5Bminute%5D=0&quest%5BdateStart%5D%5Bdate%5D%5Bday%5D=1&quest%5BdateStart%5D%5Bdate%5D%5Bmonth%5D=1&quest%5BdateStart%5D%5Bdate%5D%5Byear%5D=2011&quest%5BdateStart%5D%5Btime%5D%5Bhour%5D=0&quest%5BdateStart%5D%5Btime%5D%5Bminute%5D=0&quest%5BnbEnigma%5D=1&quest%5BquestCost%5D=1&quest%5BquestName%5D=test5&quest%5BrewardFinish%5D=1&quest%5BrewardFurther%5D=1&quest%5Bspeech%5D=test5
11-Jan-2016 16:24:32 ee563e
200 ::1 GET http://localhost/gowinquest/web/app_dev.php/admin/quest/add 11-Jan-2016 16:23:39 d0f70c