スクリプトを実行すると、次のようないくつかのエラーが表示されます:
警告: ヘッダー情報を変更できません - ヘッダーはすでに /some/file.php によって送信されています (出力は /some/file.php:12 で始まります) < 行 23<第23行
エラー メッセージに記載されている行には、header() および setcookie() 呼び出しが含まれています。
header()
setcookie()
この理由は何でしょうか?どうやって解決すればいいでしょうか?
HTTP ヘッダーを送信する前にコンテンツを送信します (setcookie または header を使用)。 HTTP ヘッダーの前に何かを出力する一般的な理由は次のとおりです:
setcookie
header
予期しないスペース (通常はファイルの先頭または末尾にあります) (以下に示すとおり):
これを回避するには、末尾の ?> を省略します。いずれにせよ、これは必要ありません。
?>
3F 3C
EF BB BF
echo
printf
readfile
passthru
> を呼び出す前のコードなど) ### 待って###
error_reporting
または
$_POST['input']
のように、引用符が欠落していることに注意してください)。
ob_start を呼び出した後のすべての出力は、 などでバッファを解放するまでメモリにバッファリングされます。 ob_end_flush。 ただし、出力バッファリングによってこれらの問題は回避できますが、アプリケーションが HTTP ヘッダーの前に HTTP 本文を出力する理由を実際に判断する必要があります。それは、電話に出てその日のことや天気について話し合ってから、電話をかけてきた相手に「間違った番号をかけた」と伝えるようなものです。
ob_end_flush
ただし、出力バッファリングによってこれらの問題は回避できますが、アプリケーションが HTTP ヘッダーの前に HTTP 本文を出力する理由を実際に判断する必要があります。それは、電話に出てその日のことや天気について話し合ってから、電話をかけてきた相手に「間違った番号をかけた」と伝えるようなものです。
HTTP ヘッダーを送信/変更する関数 出力を行う前に呼び出す必要があります。 概要⇊ それ以外の場合、呼び出しは失敗します:
HTTP ヘッダーを変更する関数には次のようなものがあります:
ヘッダー
header_remove
session_start
session_regenerate_id
setrawcookie
出力は次のようになります:
意図的ではない:
の前または ?> の後にスペース
print、
# コードの前の元の
なぜこのようなことが起こるのでしょうか?
PHP が最初の出力 (print
echo、
) を受信すると、 更新収集されたすべてのヘッダー。その後、すべての出力を送信できるようになります そうしたいのです。ただし、さらに HTTP ヘッダーを送信することはできません。 時期尚早な出力が発生している場所を見つけるにはどうすればよいですか? header() 警告にはすべての関連情報が含まれています 位置決めの問題の原因:
更新
呼び出しに失敗したスクリプトを指します。 括弧内の「
で始まります」というコメントの方が重要です。 これは、前の出力のソースを表します。この例では、auth.php です。 および ##52
auth.php
一般的な理由: 印刷、エコー
print および echo
message の前に発生することを確認してください。 それはすべて書き留められています。 出力を生成する関数には次のものが含まれます
の前に発生することを確認してください。 それはすべて書き留められています。
出力を生成する関数には次のものが含まれます
print
vprintf
trigger_error
ob_flush
var_dump
print_r
パススルー
flush
imagepng
imagejpeg
その他のユーザー定義関数。
.php ファイル内の解析されていない HTML 部分も直接出力されます。 header() 呼び出しをトリガーするスクリプト条件に注意する必要があります。 任意の 元の ブロックの前。
テンプレート スキームを使用して、処理を出力ロジックから分離します。
1 に関するものである場合、主に タグ、テキスト、または HTML の前の スペース で始まります。 リーリー
リーリー
単一の 改行を使用します。でもそうはならない このような隙間に移動された複数の改行、タブ、またはスペースを補正します。
UTF-8 BOM (バイトオーダーマーク) ほとんどのテキスト エディタではこれが表示されません。これはバイト シーケンス EF BB BF であり、UTF-8 でエンコードされたドキュメントではオプションであり、冗長です。ただし、PHP はそれを生の出力として扱う必要があります。出力では文字  として表示される場合があります。 (クライアントがドキュメントを Latin-1 として解釈した場合) または同様の「ゴミ」。
であり、UTF-8 でエンコードされたドキュメントではオプションであり、冗長です。ただし、PHP はそれを生の出力として扱う必要があります。出力では文字
(クライアントがドキュメントを Latin-1 として解釈した場合) または同様の「ゴミ」。
16 進エディタを使用することです。 *nix システムでは、通常、hexdump が利用可能です。 これらおよびその他の質問の確認を簡素化するグラフィカルなバージョンではない場合: 簡単な回避策は、ファイルを「UTF-8 (BOM なし)」として保存するようにテキスト エディタを設定することです。 または同様の命名法。多くの場合、初心者は新しいファイルを作成し、前のコードをコピーして貼り付けるという手段に頼ることがあります。
テキスト ファイルをチェックして書き換える自動ツールもあります (sed/awk代码> または recode)。 PHP の場合、特に phptags タグ tidier。 終了タグと開始タグを長い形式と短い形式に書き換えるのも簡単です 先頭と末尾の空白、Unicode、および UTF-x BOM の問題を修正しました:
sed
awk代码>
recode
phptags
インクルードまたはプロジェクト ディレクトリ全体で安全に使用できます。
の後にスペースはありますか? >
エラーの原因が後述される場合 閉じる ?> ここには、空白のテキストまたは生のテキストが書き込まれます。 現時点では、PHP 終了タグはスクリプトの実行を終了しません。その後のテキスト/スペース文字はページのコンテンツとして書き出されます。 まだ。
一般に、特に初心者の場合は、?> PHP に従うことをお勧めします。 終了タグは省略する必要があります。この により、少数の ケースが回避されます。 (通常、include()d スクリプトが原因となります。)
include()d
エラーの原因がない場合、通常は PHP 拡張機能または php.ini 設定が原因です。 コンクリート。
gzip
ob_gzhandler
extension=
別の PHP ステートメントまたは式によって警告メッセージが表示されたり、 メモが出力されますが、これも時期尚早の出力としてカウントされます。
この場合、エラーを避ける必要があります。 ステートメントの実行を遅らせるか、たとえばを使用してメッセージを抑制します。 isset() または @() - どちらでも後のデバッグに支障がない場合。
isset()
@()
php.ini に従って error_reporting または display_errors を無効にしている場合は、 その後、警告は表示されません。しかし、エラーを無視しても問題は解決しません 離れる。途中で出力した後もヘッダーを送信できません。
に従って
を無効にしている場合は、 その後、警告は表示されません。しかし、エラーを無視しても問題は解決しません 離れる。途中で出力した後もヘッダーを送信できません。
header("Location: ...") リダイレクトがサイレントに失敗する場合は非常に深刻です。 プローブ警告を推奨します。 2 つの簡単なコマンドでそれらを再度有効にします 呼び出しスクリプトの上: リーリー
リダイレクトがサイレントに失敗する場合は非常に深刻です。 プローブ警告を推奨します。 2 つの簡単なコマンドでそれらを再度有効にします 呼び出しスクリプトの上:
set_error_handler("var_dump");他のすべてのメソッドが失敗した場合。
他のすべてのメソッドが失敗した場合。
header() が失敗した場合。
が失敗した場合。
出力バッファリング は、この問題を軽減するための回避策です。通常は確実に機能しますが、そうすべきではありません 正しいアプリケーション構造をオーバーライドし、出力をコントロールから分離する 論理。その実際の目的は、Web サーバーへの分割された転送を最小限に抑えることです。
output_buffering= それでも、設定は役に立ちます。 php.iniで設定します。 または .htaccess 経由 .user.ini でも 最新の FPM/FastCGI セットアップ。 これを有効にすると、PHP は出力をすぐに Web サーバーに渡すのではなく、バッファリングできるようになります。したがって、PHP は HTTP ヘッダーを集約できます。
output_buffering=
これは、ob_start(); を呼び出して実行することもできます。 呼び出しスクリプトの上に追加します。ただし、次のような理由により信頼性が低くなります:
ob_start();
が最初のスクリプトを開始する場合でも、スペースまたは レンダリングの前に、BOM がスクランブルされ、無効な になっている可能性があります。
HTML 出力の空白を非表示にすることができます。ただし、アプリケーション ロジックがバイナリ コンテンツ (生成された画像など) を送信しようとすると、 バッファされた無関係な出力が問題になります。 (ob_clean()が必要) さらなる回避策として。 )
バッファ サイズは制限されており、デフォルト値のままにすると簡単にオーバーフローする可能性があります。 この状況は珍しいことではなく、追跡は困難です一个> それが起こったとき。
したがって、特に 2 つの方法を切り替える場合、どちらの方法も信頼性が低くなる可能性があります。 開発セットアップおよび/または運用サーバー。これが、出力バッファリングが行われる理由です。 単なる松葉杖、または厳密には回避策であると広く考えられています。
関連項目基本的な使用例 マニュアルとその他の長所と短所:
以前にヘッダー警告を受け取っていない場合は、 出力バッファリング php.ini 設定 すでに変わっています。現在/新しいサーバーでは構成されていない可能性があります。
headers_sent() を使用して確認します
headers_sent() を使用すると、いつでも次のことを検出できます。 ヘッダーを送信することはまだ可能です。これは条件付き印刷に便利です 情報を取得するか、他のフォールバック ロジックを適用します。 リーリー
アプリケーションの構造的に修正が難しい場合は、簡単な (ただし、 少し専門的ではありません) リダイレクトを許可する方法は HTML を挿入することです ラベル。リダイレクトは次の方法で実現できます:
または短い遅延:
を超えるセクションを使用すると、無効な HTML が発生します。 ほとんどのブラウザは依然としてそれを受け入れます。
代わりに、JavaScript リダイレクト ページのリダイレクトに使用できます:
これは通常、 ソリューションよりも HTML 準拠ですが、 その結果、JavaScript 対応クライアントへの依存関係が生じます。
ただし、両方のメソッドは、実際の HTTP header() が失敗した場合に許容可能なフォールバックを生成します。 通話が失敗しました。理想的には、これを常にユーザーフレンドリーなメッセージと組み合わせてください。 クリック可能なリンクは最後の手段として使用してください。 (例: http_redirect() PECL 拡張機能はこれに対応します。 )
と
も影響を受ける理由
setcookie() と session_start() はどちらも Set-Cookie: HTTP ヘッダーを送信する必要があります。 したがって、同じ条件が適用され、同様のエラー メッセージが生成されます。 出力が早すぎる場合に使用されます。
はどちらも
HTTP ヘッダーを送信する必要があります。 したがって、同じ条件が適用され、同様のエラー メッセージが生成されます。 出力が早すぎる場合に使用されます。
HTTP ヘッダーを送信する前にコンテンツを送信します (
setcookie
またはheader
を使用)。 HTTP ヘッダーの前に何かを出力する一般的な理由は次のとおりです:予期しないスペース (通常はファイルの先頭または末尾にあります) (以下に示すとおり):
リーリーこれを回避するには、末尾の
?>
を省略します。いずれにせよ、これは必要ありません。3F 3C
で始まる必要があります。ファイルの先頭から BOMEF BB BF
を安全に削除できます。echo
、printf
、readfile
、passthru
、> を呼び出す前のコードなど) ### 待って###
display_errors または
error_reporting
構成を変更することは可能ですが、問題を解決する必要があります。 一般的な原因は、配列内の未定義の要素にアクセスすることです (例: emptyまたは
isset# を使用せずに$_POST['input']
# を使用して入力が設定されているかどうかをテストするか、文字列リテラルの代わりに未定義の定数を使用します ($_POST[input]のように、引用符が欠落していることに注意してください)。
ob_start を呼び出した後のすべての出力は、 などでバッファを解放するまでメモリにバッファリングされます。
ob_end_flush
。ただし、出力バッファリングによってこれらの問題は回避できますが、アプリケーションが HTTP ヘッダーの前に HTTP 本文を出力する理由を実際に判断する必要があります。それは、電話に出てその日のことや天気について話し合ってから、電話をかけてきた相手に「間違った番号をかけた」と伝えるようなものです。
ヘッダーを送信する前に出力がありません!
HTTP ヘッダーを送信/変更する関数 出力を行う前に呼び出す必要があります。 概要⇊ それ以外の場合、呼び出しは失敗します:
HTTP ヘッダーを変更する関数には次のようなものがあります:
ヘッダー
/header_remove
session_start
/session_regenerate_id
setcookie
/setrawcookie
出力は次のようになります:
意図的ではない:
の前または
?>
の後にスペース#########故意に:######-
を表示する
返事。 PHP スクリプトは主に HTML コンテンツを生成し、
Web サーバーに送信される HTTP/CGI ヘッダーのセット:
リーリーprint、
echo、および出力を生成するその他の関数-
セクション。 -
これは、出力前にヘッダーを送信する必要がある理由を理解するために必要です。
一般的な
HTTP# コードの前の元の
なぜこのようなことが起こるのでしょうか?
ページ/出力は常に
タイトルの後に続きます。 PHP は合格する必要があります まずヘッダーが Web サーバーに送信されます。これは一度しか実行できません。 二重ラッピング後は変更できなくなります。PHP が最初の出力 (print
、echo、
) を受信すると、
時期尚早な出力が発生している場所を見つけるにはどうすればよいですか?
header() 警告にはすべての関連情報が含まれています 位置決めの問題の原因:
ここで「100行目」は、更新
収集されたすべてのヘッダー。その後、すべての出力を送信できるようになります そうしたいのです。ただし、さらに HTTP ヘッダーを送信することはできません。header()
呼び出しに失敗したスクリプトを指します。
括弧内の「
出力はで始まります」というコメントの方が重要です。 これは、前の出力のソースを表します。この例では、
行。ここで、時期尚早の出力を探す必要があります。auth.php
です。 および ##52一般的な理由:
印刷、エコー
print および echo
ステートメントを意図的に出力すると、HTTP ヘッダーを送信する機会が終了します。この状況を回避するには、申請プロセスを再構築する必要があります。関数- の使用
そしてテンプレートソリューション。
-
-
-
-
- フォーム処理コードをスクリプトの上に置きます。
- 一時文字列変数を使用してメッセージを延期します。
- 実際の出力ロジックと混合 HTML 出力は最後に配置する必要があります。
-
- UTF-8 BOM
改行とスペースだけでも問題になる可能性があります。しかし「目に見えないもの」もあります これを引き起こす可能性のある文字シーケンス。最も有名なのは、
これにより、問題をできるだけ早く検出することが容易になります。他の編集者は認識するかもしれません これは [ファイル]/[設定] メニューにあります (Windows のメモ帳は認識し、 ###問題を解く###)、 BOM の存在を確認するもう 1 つのオプションは、
-
-
- 時々
- ただし、デュアルロードされた
-
header()
呼び出しがmessage
の前に発生することを確認してください。 それはすべて書き留められています。
出力を生成する関数には次のものが含まれます
print
、echo
、printf
、vprintf
trigger_error
、ob_flush
、ob_end_flush
、var_dump
、print_r
readfile
、パススルー
、flush
、imagepng
、imagejpeg
その他のユーザー定義関数。
元の HTML エリア
.php ファイル内の解析されていない HTML 部分も直接出力されます。
リーリーheader()
呼び出しをトリガーするスクリプト条件に注意する必要があります。 任意の 元のブロックの前。
テンプレート スキームを使用して、処理を出力ロジックから分離します。
# その前のスペースは「script.php line 1」の警告を意味します
警告がインライン出力1
同様に、これは追加のスクリプトまたはスクリプト セクションでも発生する可能性があります:に関するものである場合、主に タグ、テキスト、または HTML の前の スペース で始まります。 リーリー
リーリー
PHP は実際には、終了タグの後に単一の 改行を使用します。でもそうはならない このような隙間に移動された複数の改行、タブ、またはスペースを補正します。
UTF-8 BOM (バイトオーダーマーク) ほとんどのテキスト エディタではこれが表示されません。これはバイト シーケンス EF BB BF
特にグラフィカル エディターと Java ベースの IDE はこれに気づきません。 存在してください。 (Unicode 標準で要求されているように) それを視覚化しません。 ただし、ほとんどのプログラマーとコンソール エディターは次のことを行います:であり、UTF-8 でエンコードされたドキュメントではオプションであり、冗長です。ただし、PHP はそれを生の出力として扱う必要があります。出力では文字
 として表示される場合があります。(クライアントがドキュメントを Latin-1 として解釈した場合) または同様の「ゴミ」。
16 進エディタを使用することです。 *nix システムでは、通常、hexdump が利用可能です。 これらおよびその他の質問の確認を簡素化するグラフィカルなバージョンではない場合:
簡単な回避策は、ファイルを「UTF-8 (BOM なし)」として保存するようにテキスト エディタを設定することです。 または同様の命名法。多くの場合、初心者は新しいファイルを作成し、前のコードをコピーして貼り付けるという手段に頼ることがあります。
修正ユーティリティ
テキスト ファイルをチェックして書き換える自動ツールもあります (
リーリーsed
/awk代码>
またはrecode
)。 PHP の場合、特にphptags
タグ tidier。 終了タグと開始タグを長い形式と短い形式に書き換えるのも簡単です 先頭と末尾の空白、Unicode、および UTF-x BOM の問題を修正しました:インクルードまたはプロジェクト ディレクトリ全体で安全に使用できます。
の後にスペースはありますか? >
エラーの原因が後述される場合 閉じる
?>
ここには、空白のテキストまたは生のテキストが書き込まれます。 現時点では、PHP 終了タグはスクリプトの実行を終了しません。その後のテキスト/スペース文字はページのコンテンツとして書き出されます。 まだ。一般に、特に初心者の場合は、
?>
PHP に従うことをお勧めします。 終了タグは省略する必要があります。この により、少数の ケースが回避されます。 (通常、include()d
スクリプトが原因となります。)エラーの原因は「不明な行 0」と呼ばれます
エラーの原因がない場合、通常は PHP 拡張機能または php.ini 設定が原因です。 コンクリート。
gzip
ストリーム エンコード設定 またはob_gzhandler
。extension=
モジュールでも構いません 暗黙的な PHP 起動/警告メッセージを生成します。前のエラー メッセージ
別の PHP ステートメントまたは式によって警告メッセージが表示されたり、 メモが出力されますが、これも時期尚早の出力としてカウントされます。
この場合、エラーを避ける必要があります。 ステートメントの実行を遅らせるか、たとえばを使用してメッセージを抑制します。
isset()
または@()
- どちらでも後のデバッグに支障がない場合。エラーメッセージなし
php.ini
したがって、に従って
error_reportingまたは
display_errorsを無効にしている場合は、 その後、警告は表示されません。しかし、エラーを無視しても問題は解決しません 離れる。途中で出力した後もヘッダーを送信できません。
header("Location: ...")
またはリダイレクトがサイレントに失敗する場合は非常に深刻です。 プローブ警告を推奨します。 2 つの簡単なコマンドでそれらを再度有効にします 呼び出しスクリプトの上:
リーリーset_error_handler("var_dump");
リダイレクトヘッダーについて言えば、常に次のようなイディオムを使用する必要があります。 これは最終的なコード パスです:他のすべてのメソッドが失敗した場合。
リーリー
ユーザーメッセージを出力する実用的な機能であることが最善ですheader()
回避策としての出力バッファリングが失敗した場合。
出力バッファリング は、この問題を軽減するための回避策です。通常は確実に機能しますが、そうすべきではありません 正しいアプリケーション構造をオーバーライドし、出力をコントロールから分離する 論理。その実際の目的は、Web サーバーへの分割された転送を最小限に抑えることです。
output_buffering=
それでも、設定は役に立ちます。 php.iniで設定します。 または .htaccess 経由 .user.ini でも 最新の FPM/FastCGI セットアップ。これを有効にすると、PHP は出力をすぐに Web サーバーに渡すのではなく、バッファリングできるようになります。したがって、PHP は HTTP ヘッダーを集約できます。
これは、
ob_start();
を呼び出して実行することもできます。 呼び出しスクリプトの上に追加します。ただし、次のような理由により信頼性が低くなります:が最初のスクリプトを開始する場合でも、スペースまたは レンダリングの前に、BOM がスクランブルされ、無効な になっている可能性があります。
HTML 出力の空白を非表示にすることができます。ただし、アプリケーション ロジックがバイナリ コンテンツ (生成された画像など) を送信しようとすると、 バッファされた無関係な出力が問題になります。 (ob_clean()が必要) さらなる回避策として。 )
バッファ サイズは制限されており、デフォルト値のままにすると簡単にオーバーフローする可能性があります。 この状況は珍しいことではなく、追跡は困難です一个> それが起こったとき。
したがって、特に 2 つの方法を切り替える場合、どちらの方法も信頼性が低くなる可能性があります。 開発セットアップおよび/または運用サーバー。これが、出力バッファリングが行われる理由です。 単なる松葉杖、または厳密には回避策であると広く考えられています。
関連項目基本的な使用例 マニュアルとその他の長所と短所:
しかし、他のサーバーでも動作します。 ?
以前にヘッダー警告を受け取っていない場合は、 出力バッファリング php.ini 設定 すでに変わっています。現在/新しいサーバーでは構成されていない可能性があります。
headers_sent() を使用して確認します
headers_sent()
有用なフォールバック ソリューションは次のとおりです:を使用すると、いつでも次のことを検出できます。 ヘッダーを送信することはまだ可能です。これは条件付き印刷に便利です 情報を取得するか、他のフォールバック ロジックを適用します。 リーリー
HTML
タグ
アプリケーションの構造的に修正が難しい場合は、簡単な (ただし、 少し専門的ではありません) リダイレクトを許可する方法は HTML を挿入することです
リーリーラベル。リダイレクトは次の方法で実現できます:
または短い遅延:
リーリーを超えるセクションを使用すると、無効な HTML が発生します。 ほとんどのブラウザは依然としてそれを受け入れます。
JavaScript リダイレクト
代わりに、JavaScript リダイレクト ページのリダイレクトに使用できます:
リーリーこれは通常、
ソリューションよりも HTML 準拠ですが、 その結果、JavaScript 対応クライアントへの依存関係が生じます。
ただし、両方のメソッドは、実際の HTTP header() が失敗した場合に許容可能なフォールバックを生成します。 通話が失敗しました。理想的には、これを常にユーザーフレンドリーなメッセージと組み合わせてください。 クリック可能なリンクは最後の手段として使用してください。 (例: http_redirect() PECL 拡張機能はこれに対応します。 )
setcookie()
と
session_start()も影響を受ける理由
setcookie()
(もちろん、ブラウザの Cookie を無効にすることによっても影響を受けます) 代理店の問題でも。セッション機能も明らかに無料に依存しています。 ディスク容量やその他の php.ini 設定など)と
session_start()はどちらも
Set-Cookie:HTTP ヘッダーを送信する必要があります。 したがって、同じ条件が適用され、同様のエラー メッセージが生成されます。 出力が早すぎる場合に使用されます。
Google は、同様の議論の- 長いリストを提供しています。
もちろん、Stack Overflow は
- 多くの特定のケース . もカバーしています。
WordPress FAQ では、- 「ヘッダー送信済み」という警告の問題を解決する方法について説明しています。 一般的な方法です。
Adobe コミュニティ: - PHP 開発: リダイレクトが機能しない理由 (ヘッダーは送信済み)
Nucleus FAQ: - 「ヘッダー送信済み」とはどういう意味ですか?
より詳細な説明の 1 つは、- HTTP ヘッダーと PHP header() 関数です。NicholasSolutions によるチュートリアルです。 (インターネット アーカイブへのリンク)。
HTTP について詳しく説明し、スクリプトを書き直すためのガイドラインをいくつか示します。