Symfony2启动会话失败:已由PHP启动


Symfony2 Failed to start the session: already started by PHP

我遇到了一个非常奇怪的问题,看起来像这样:

[2014-11-06 11:21:13] request.INFO: Matched route "core_timetracking_new_user" (parameters: "_controller": "Bricks'Custom'CoreBundle'Controller'TimeTrackingController::newuserAction", "_route": "core_timetracking_new_user") [] []
[2014-11-06 11:21:13] request.CRITICAL: Uncaught PHP Exception RuntimeException: "Failed to start the session: already started by PHP." at /var/cache/app/prod/classes.php line 113 {"exception":"[object] (RuntimeException: Failed to start the session: already started by PHP. at /var/cache/app/prod/classes.php:113)"} []

奇怪的是,我不启动或使用会话,这是控制器代码:

/**
 * @View
 */
public function newuserAction()
{
    $trackingService=$this->get('core.timetracking_service');
    $user= new TimeTrackingUser();
    $request=$this->getRequest();
    $form = $this->createFormBuilder($user)
        ->add('name','text')
        ->add('email','text')
        ->add('pass','password')
        ->add('save', 'submit', array('label' => 'Erstellen'))
        ->getForm();
    $form->handleRequest($request);
    if ($form->isValid()) {
        $trackingService->persistUser($form->getData());
        return $this->redirect($this->generateUrl('core_timetracking_user_list'));
    }else {
        return array(
            'form' => $form->createView()
        );
    }
}

而这个动作的效果非常好

/**
 * @View
 */
public function listuserAction()
{
    $request=$this->getRequest();
    $trackingService=$this->get('core.timetracking_service');    
    $users=$trackingService->getAllUsers();
    return array(
        'users' => $users
    );
}

所以唯一的区别是我使用

$form->handleRequest($request); 

还检查了我的所有文件AppKernel等是否都以

两个动作(工作的和不工作的)在同一个控制器中

一旦呈现表单,Symfony就会自动启动一个会话来存储CSRF保护的令牌:http://symfony.com/doc/current/book/forms.html#csrf-保护

您可以禁用CSRF保护,但默认情况下是启用的。

@rakete:
我唯一的额外想法是更改会话文件的存储方式(例如文件系统、数据库、内存等)。请参阅此处:http://symfony.com/doc/current/components/http_foundation/session_configuration.html

您应该检查是否有启动新会话的侦听器

你不能有一个new Session()的听众。您应该像在操作方法中那样使用请求会话。


我有一个onKernelController侦听器,它用new Session()启动了一个新会话,然后当表单尝试生成csrf令牌时,它会检查会话是否存在并抛出异常。