log > Failed to start the session because headers have already been sent by "" at line 0
環境
PHP 5.6.22 Symfony 2.8 FOSRestBundle 2.0
エラー
クライアント側からPOSTでSymfonyのAPIにデータを送り、その後データを更新して更新したデータをJSONで返すプログラムを作っていたところ、次のようなエラーが出た。
Uncaught PHP Exception RuntimeException: Failed to start the session because headers have already been sent by "" at line 0
しばらくSymfonyのエラーログを見たり、FOSRestBundleのエラーを追っていたが、全く情報がつかめなかった。しばらくして Advanced REST client でデータを送ったところ、以下の出力が得られた。
<br />
<b>Deprecated</b>: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in <b>Unknown</b> on line <b>0</b><br />
<br />
<b>Warning</b>: Cannot modify header information - headers already sent in <b>Unknown</b> on line <b>0</b><br />
{"code":500,"message":"Failed to start the session because headers have already been sent by \"\" at line 0."}
クライアント側ではこのようなエラーが取得できていた。(フロント側はPromiseを使っていたのでresponse.json()
でパースエラーになってもPHPでエラー出てるから同じでしょ?と思っていたのが間違いだったようだ。)
エラーの内容は、「always_populate_raw_post_data
は非推奨だから-1にしろ」とそれに付随するものだったようだ。これはPHPのバグらしく、PHP :: Doc Bug #67991 :: always_populate_raw_post_data deprecation warning buggyで報告されている。
そして、このエラーがSymfonyのheaderが出力される前に出ていたため、Symfony側のエラーで「sessionの開始前にレンダリングするな」となっていたのではないかと思われる。
このあと、php.iniのalways_populate_raw_post_data
に-1を設定したらエラーが解決した。