Unable to emit headers. 見過ごすことも可能・・・だがしかし

2020年9月3日

f:id:ryurin-business:20200121112918p:plain
php

Unable to emit headers.

PHP開発をやってるとWarning(512)としてすこぶる主張してくるあいつです。

基本この方は

header関数よりも前にecho文などで何かを出力した際に

出てきます。

理由はHTMLの文法としてNGだからね。

なので、

echo '俺です';
header("Content-Type: text/html; charset=UTF-8");

こんなことしようものなら全力で叩かれます。

でもね、こんなことせずとも彼が主張してくることもあります。

以下例文

$result = $this->pdfFacade->downloadReceiptXml($subscribe);
if (isset($result)) {

header("Content-Type: {$result['ContentType']}");
    header('Content-Disposition: attachment; filename="sample.xml"');
    echo $result['Body'];
}

この例では$resultにはAWSのS3からXMLをダウンロードした結果が取得されています。

それをsample.xmlというファイル名でブラウザ経由でダウンロードしようとしているものです。

一見、XMLは正常にダウンロードされます。

が、しかし!

XMLの中身を見てみると、正常XML文の後半に彼は主張してきます。

<pre class="cake-error"><a href="javascript:void(0);" onclick="document.getElementById('cakeErr5e265b1e92b5e-trace’).style.display = (document.getElementById('cakeErr5e265b1e92b5e-trace’).style.display == 'none’ ? " : 'none’);"><b>Warning</b> (512)</a>: Unable to emit headers. Headers sent in file=/var/www/html/app/src/Controller/SampleController.php line=140 [<b>CORE/src/Http/ResponseEmitter.php</b>

見た目は素直なXMLだと思って、取引先とかに渡すと「読み込みへんやん」と叩かれるのが落ちです。

システムから出力されたファイルはちゃんと中身を確認しましょう

というわけで原因と対策です。

原因

今回の例ではCakePHP3.8にて起こった事象です。

このファンクションはViewで表示せずにControllerで完結する処理である

そのためctpファイルは存在しない

XML文字列をそのままechoしていた

これらが問題となります。なのでechoする際に意図しない文字列がheaderに入って激おこなんだろうと推測。

対策

ではどうやるか。

このファンクションはViewで表示せずにControllerで完結する処理である

そのためctpファイルは存在しない

 であればしっかりファンクション内で

$this->autoRender = false;

としておきましょう。勝手にレイアウトと紐付けるな、という処理ですね。

文字コードのことも考えて

$this->response->charset('UTF-8');

も一緒に書いておくと素敵です。

あとは出力時に、

header("Content-Type: {$result['ContentType']}");
header('Content-Disposition: attachment; filename="sample.xml"');
$this->response->body($result['Body']);

とすれば完璧。

こうすることで、レスポンスのBodyとして$result['Body’]は出力されるので間違ってもheader内に文字が混入されることはないわけです。

これでXMLさんもご満悦のご様子。

これにて一件落着。