検索

ホームページ  >  に質問  >  本文

PHP の「ヘッダーはすでに送信されました」エラーを修正する方法

スクリプトを実行すると、次のようないくつかのエラーが表示されます:

警告: ヘッダー情報を変更できません - ヘッダーはすでに /some/file.php によって送信されています (出力は /some/file.php:12 で始まります) < 行 23<第23行

エラー メッセージに記載されている行には、header() および setcookie() 呼び出しが含まれています。

この理由は何でしょうか?どうやって解決すればいいでしょうか?

P粉210405394P粉210405394416日前568

全員に返信(2)返信します

  • P粉071602406

    P粉0716024062023-10-10 11:29:08

    HTTP ヘッダーを送信する前にコンテンツを送信します (setcookie または header を使用)。 HTTP ヘッダーの前に何かを出力する一般的な理由は次のとおりです:

    • 予期しないスペース (通常はファイルの先頭または末尾にあります) (以下に示すとおり):

      リーリー

    これを回避するには、末尾の ?> を省略します。いずれにせよ、これは必要ありません。

    ob_start を呼び出した後のすべての出力は、 などでバッファを解放するまでメモリにバッファリングされます。 ob_end_flush ただし、出力バッファリングによってこれらの問題は回避できますが、アプリケーションが HTTP ヘッダーの前に HTTP 本文を出力する理由を実際に判断する必要があります。それは、電話に出てその日のことや天気について話し合ってから、電話をかけてきた相手に「間違った番号をかけた」と伝えるようなものです。

    返事
    0
  • P粉087951442

    P粉0879514422023-10-10 09:54:05

    ヘッダーを送信する前に出力がありません!

    HTTP ヘッダーを送信/変更する関数 出力を行う前に呼び出す必要があります。 概要⇊ それ以外の場合、呼び出しは失敗します:

    HTTP ヘッダーを変更する関数には次のようなものがあります:

    出力は次のようになります:

      #########故意に:######
    • print

      echo
        、および出力を生成するその他の関数
      • # コードの前の元の
      • セクション。
      • なぜこのようなことが起こるのでしょうか?
      • これは、出力前にヘッダーを送信する必要がある理由を理解するために必要です。 一般的な
      HTTP
    • を表示する 返事。 PHP スクリプトは主に HTML コンテンツを生成し、 Web サーバーに送信される HTTP/CGI ヘッダーのセット:
    リーリー

    ページ/出力は常に

    タイトルの後に続きます。 PHP は合格する必要があります まずヘッダーが Web サーバーに送信されます。これは一度しか実行できません。 二重ラッピング後は変更できなくなります。

    PHP が最初の出力 (print

    echo

    ) を受信すると、 更新収集されたすべてのヘッダー。その後、すべての出力を送信できるようになります そうしたいのです。ただし、さらに HTTP ヘッダーを送信することはできません。 時期尚早な出力が発生している場所を見つけるにはどうすればよいですか? header() 警告にはすべての関連情報が含まれています 位置決めの問題の原因:

    ここで「100行目」は、

    header()

    呼び出しに失敗したスクリプトを指します。 括弧内の「

    出力は

    で始まります」というコメントの方が重要です。 これは、前の出力のソースを表します。この例では、auth.php です。 および ##52

    行。ここで、時期尚早の出力を探す必要があります。

    一般的な理由: 印刷、エコー

    print および echo

    ステートメントを意図的に出力すると、HTTP ヘッダーを送信する機会が終了します。この状況を回避するには、申請プロセスを再構築する必要があります。
      関数
    1. の使用 そしてテンプレートソリューション。

      header()

      呼び出しが

      message の前に発生することを確認してください。 それはすべて書き留められています。 出力を生成する関数には次のものが含まれます

      • printechoprintfvprintf
      • trigger_errorob_flushob_end_flushvar_dumpprint_r
      • readfileパススルーflushimagepngimagejpeg


      その他のユーザー定義関数。

    2. 元の HTML エリア

      .php ファイル内の解析されていない HTML 部分も直接出力されます。 header() 呼び出しをトリガーするスクリプト条件に注意する必要があります。 任意の 元の ブロックの前。

      リーリー

      テンプレート スキームを使用して、処理を出力ロジックから分離します。

      • フォーム処理コードをスクリプトの上に置きます。
      • 一時文字列変数を使用してメッセージを延期します。
      • 実際の出力ロジックと混合 HTML 出力は最後に配置する必要があります。

    3. # その前のスペースは「script.php line 1」の警告を意味します

      警告がインライン出力

      1 に関するものである場合、主に タグ、テキスト、または HTML の前の スペース で始まります。 リーリー

      同様に、これは追加のスクリプトまたはスクリプト セクションでも発生する可能性があります:

      リーリー

      PHP は実際には、終了タグの後に

      単一の 改行を使用します。でもそうはならない このような隙間に移動された複数の改行、タブ、またはスペースを補正します。

    4. UTF-8 BOM

      改行とスペースだけでも問題になる可能性があります。しかし「目に見えないもの」もあります これを引き起こす可能性のある文字シーケンス。最も有名なのは、

      UTF-8 BOM (バイトオーダーマーク) ほとんどのテキスト エディタではこれが表示されません。これはバイト シーケンス EF BB BF であり、UTF-8 でエンコードされたドキュメントではオプションであり、冗長です。ただし、PHP はそれを生の出力として扱う必要があります。出力では文字  として表示される場合があります。 (クライアントがドキュメントを Latin-1 として解釈した場合) または同様の「ゴミ」。

      特にグラフィカル エディターと Java ベースの IDE はこれに気づきません。 存在してください。 (Unicode 標準で要求されているように) それを視覚化しません。 ただし、ほとんどのプログラマーとコンソール エディターは次のことを行います:

      これにより、問題をできるだけ早く検出することが容易になります。他の編集者は認識するかもしれません これは [ファイル]/[設定] メニューにあります (Windows のメモ帳は認識し、 ###問題を解く###)、 BOM の存在を確認するもう 1 つのオプションは、

      16 進エディタを使用することです。 *nix システムでは、通常、hexdump が利用可能です。 これらおよびその他の質問の確認を簡素化するグラフィカルなバージョンではない場合: 簡単な回避策は、ファイルを「UTF-8 (BOM なし)」として保存するようにテキスト エディタを設定することです。 または同様の命名法。多くの場合、初心者は新しいファイルを作成し、前のコードをコピーして貼り付けるという手段に頼ることがあります。

      修正ユーティリティ

      テキスト ファイルをチェックして書き換える自動ツールもあります (sed/awk または recode)。 PHP の場合、特に phptags タグ tidier。 終了タグと開始タグを長い形式と短い形式に書き換えるのも簡単です 先頭と末尾の空白、Unicode、および UTF-x BOM の問題を修正しました:

      リーリー

      インクルードまたはプロジェクト ディレクトリ全体で安全に使用できます。

    5. の後にスペースはありますか? >

      エラーの原因が後述される場合 閉じる ?> ここには、空白のテキストまたは生のテキストが書き込まれます。 現時点では、PHP 終了タグはスクリプトの実行を終了しません。その後のテキスト/スペース文字はページのコンテンツとして書き出されます。 まだ。

      一般に、特に初心者の場合は、?> PHP に従うことをお勧めします。 終了タグは省略する必要があります。この により、少数の ケースが回避されます。 (通常、include()d スクリプトが原因となります。)

    6. エラーの原因は「不明な行 0」と呼ばれます

      エラーの原因がない場合、通常は PHP 拡張機能または php.ini 設定が原因です。 コンクリート。

      • 時々 gzip ストリーム エンコード設定 または ob_gzhandler
      • ただし、デュアルロードされた extension= モジュールでも構いません 暗黙的な PHP 起動/警告メッセージを生成します。

    7. 前のエラー メッセージ

      別の PHP ステートメントまたは式によって警告メッセージが表示されたり、 メモが出力されますが、これも時期尚早の出力としてカウントされます。

      この場合、エラーを避ける必要があります。 ステートメントの実行を遅らせるか、たとえばを使用してメッセージを抑制します。 isset() または @() - どちらでも後のデバッグに支障がない場合。

    エラーメッセージなし

    php.ini に従って error_reporting または display_errors を無効にしている場合は、 その後、警告は表示されません。しかし、エラーを無視しても問題は解決しません 離れる。途中で出力した後もヘッダーを送信できません。

    したがって、

    header("Location: ...") リダイレクトがサイレントに失敗する場合は非常に深刻です。 プローブ警告を推奨します。 2 つの簡単なコマンドでそれらを再度有効にします 呼び出しスクリプトの上: リーリー

    または

    set_error_handler("var_dump");他のすべてのメソッドが失敗した場合。

    リダイレクトヘッダーについて言えば、常に次のようなイディオムを使用する必要があります。 これは最終的なコード パスです:

    リーリー

    ユーザーメッセージを出力する実用的な機能であることが最善です

    header() が失敗した場合。

    回避策としての出力バッファリング

    PHP

    出力バッファリング は、この問題を軽減するための回避策です。通常は確実に機能しますが、そうすべきではありません 正しいアプリケーション構造をオーバーライドし、出力をコントロールから分離する 論理。その実際の目的は、Web サーバーへの分割された転送を最小限に抑えることです。

    1. output_buffering= それでも、設定は役に立ちます。 php.iniで設定します。 または .htaccess 経由 .user.ini でも 最新の FPM/FastCGI セットアップ。
      これを有効にすると、PHP は出力をすぐに Web サーバーに渡すのではなく、バッファリングできるようになります。したがって、PHP は HTTP ヘッダーを集約できます。

    2. これは、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()session_start() はどちらも Set-Cookie: HTTP ヘッダーを送信する必要があります。 したがって、同じ条件が適用され、同様のエラー メッセージが生成されます。 出力が早すぎる場合に使用されます。

    (もちろん、ブラウザの Cookie を無効にすることによっても影響を受けます) 代理店の問題でも。セッション機能も明らかに無料に依存しています。 ディスク容量やその他の php.ini 設定など)

    その他のリンク

  • キャンセル返事