Question

I have a Controller action which iterates over the an array of Entities and creates a Form for each, and then renders them in a Twig template, like so:

public function siteTestAction() {
    $api = $this->get('product_model');
    $result = $api->findProductByCode("2000082");

    $array_forms = Array();

    foreach ($result as $prod)
    {
        $form = $this->createForm('pos_product', $prod, array('action' => $this->generateUrl('receive_form')));
        $array_forms[] = $form->createView();

    }

    return $this->render('AEBikePOSSyncBundle:Default:array_form.html.twig', array(
        'data' => $array_forms,
    ));
}

Loading this gives me an error of "Failed to start the session because headers have already been sent by "" at line 0."

This controller action was a re-write of a different action that worked perfectly. I tried eliminating differences between them but there are many, for example the new one uses Guzzle to consume the API. Almost all of the differences are behind the findProductsByCode() method, which just returns an array of entities.

The last three items in the stack trace are:

  • NativeSessionStorage ->start ()
  • at Session ->start ()
  • at SessionCsrfProvider ->getSessionId ()

So I started looking as csrf_protection. As soon as I disable csrf_protection in the FormType class, the error goes away and everything works.

The original working action DOES use csrf_protection, which I can verify by viewing the source of the form and seeing the token field.

So, why would csrf_protection cause this error in one action but not another action, using the same FormType?

**Edit: I have eliminated as many differences as I can between my two routes, and the only difference I can't eliminate is that one uses Guzzle to download an API and one uses cURL. I guess I'm going to have to look through Guzzle files for extra spaces or bad encoding?

**Edit2: Well, I narrowed it down and found the culprit, but I'm not sure what to do about it. I use Guzzle to consume the API, and my Guzzle class has a Listener which will set some status variables every time a request is sent. This code is in my Guzzle Class constructor:

    $this->getEventDispatcher()->addListener('request.complete', function(Event $event) {

        $this->status_code = (int) $event['response']->getStatusCode();
        $this->reason_phrase = $event['response']->getReasonPhrase();;
        $this->url = $event['request']->getUrl();

    });

If I remove that block, everything works. So now the question, why? I want to keep this listener of course.

Was it helpful?

Solution

Ugh, I found an errant flush(); statement deep in my code. Definitely was not looking for that. So many red herrings on this one...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top