I have an action in Symfony2 controller that is sending out a response back to the client (as detailed here). After the function sends out the response, I have an event subscriber that listens for onkernelTerminate event since I'll be doing some heavy work after the response is sent to the client.
Everything seems to be working normally for the part that's doing the heavy work except that there's line in the code that is referencing a service that utilizes Session, which needs it for storing tokens and eventually communicating with an external API.
The error is of course: Failed to start the session because headers have already been sent.
Is there a way to start a Session even headers have been sent? Or what would be a better approach to handle this issue?
I ended up fixing this issue by getting the session from the incoming request and storing it to a local variable in my action controller, then made sure the session got activated or started:
use Symfony\Component\HttpFoundation\Request;
public function myFunctionAction(Request $request) {
$session = $request->getSession();
$session->start();
next, I immediately sent the response and headers to the client:
ob_start();
$response = new Response('Status: OK', 200);
echo $response; // send the response
header('Connection: close');
header('Content-Length: ' . ob_get_length());
ob_end_flush();
if (ob_get_level() > 0) {
ob_flush();
}
flush();
Then the code continues doing the heavy work as usual. The key to solving this issue was, however, to make sure that the service that utilizes Session to provide the option to others who will be referencing it to save or not save the session within the service. If the session gets saved then it won't be active anymore and it gets closed, and once it is closed you cannot start it again since headers were already sent. The client code that references the service should however save and close the session in the end of course.
I ended up not listening for the kernel.terminate event since there was no need for it in my case.