この記事は、stackoverflow に関する質問に対する回答です。この回答は、他の回答のアイデアに焦点を当ててまとめたものです。そのため、今後「ヘッダーはすでに送信されました」エラーが発生した場合は、次の方法で直接確認できます。あるいは、コーディングや設計においてそのような問題を単に回避することもできます。
ヘッダーを送信する前に出力はありません
HTTP ヘッダー情報を送信または変更するメソッドは、出力が出力される前に呼び出す必要があります。それ以外の場合、呼び出しはエラーになります:
警告: ヘッダー情報を変更することはできません - ヘッダーはすでに送信されました (outputが script:line で開始されました)
これらのメソッドは HTTP ヘッダー情報を変更 (修正) できます:
- header / header_remove
- session_start / session_regenerate_id
- setcookie / setrawcookie
出力は次のとおりです:
- 意図的でない:
- UTF-8 BOM
- 意図的:
- print 、 echo などの出力を生成するメソッド
- ブロック
このエラーが発生する理由
出力を送信する前に HTTP ヘッダーが必要な理由を理解するため、典型的な HTTP 応答を見てみる必要があります。 PHP スクリプトは主に HTML の生成に使用されますが、一連の HTTP/CGI ヘッダー情報も Web サーバーに送信します。
HTTP/1.1 200 OKPowered-By: PHP/5.3.7Vary: Accept-EncodingContent-Type: text/html; charset=utf-8<html><head><title>PHP page output page</title></head><body><h1 id="Content">Content</h1> <p>Some more output follows...</p>and <a href="/"> <img src=internal-icon-delayed alt="PHPの「ヘッダーはすでに送信されました」エラーを解決する" > </a>
ページまたは出力は常にヘッダー情報に従います。 PHP は最初にヘッダー情報を Web サーバーに送信する必要があり、送信できるのは 1 回だけであり、その後はヘッダー情報を変更できません。
PHP が最初に出力 ( print 、 echo 、 ) を受け取ると、収集されたすべてのヘッダー情報がクリアされます。この後、出力したい内容はすべて出力できますが、HTTP ヘッダー情報を送信することはできません。
出力がどこで生成されるかを事前に確認するにはどうすればよいですか?
header() ヘッダー情報には、問題に関連するすべての情報が含まれています:
警告: ヘッダー情報は変更できません - ヘッダーは既に送信されています (出力は /www/usr2345/htdocs/auth.php:52 で開始されました) in /www / usr2345/htdocs/index.php 100 行目
上記の警告では、100 行目は header() の呼び出しが失敗したスクリプトの行番号を指しています。
括弧内の出力開始メッセージの方が重要です。 header() の前にある出力のソースを示します。この場合、それは auth.php の 52 行目であり、そこが時期尚早の出力を探している場所です。
一般的な理由は次のとおりです:
-
print、echo
意図的な print および echo ステートメントの出力により、HTTP ヘッダー情報を出力する機会が中断されます。この動作を回避するには、関数とテンプレートを使用して、情報が書き出される前に header() 呼び出しが行われるようにアプリケーション フローを再編成する必要があります。
出力を生成するメソッドには次が含まれます:
- print、echo、printf、vprintf
- trigger_error、ob_flush、ob_end_flush、var_dump、print_r
- readfile、passthru、flush、imagepng、imagejpeg
その他のユーザー定義の定義方法。
-
Raw HTML
PHP ファイル内の解析されていない HTML チャンクも出力されます。 header() の呼び出しをトリガーするスクリプト内の条件はすべて、 ブロックの前に宣言する必要があります。
-
警告が 1 行の出力を指している場合、それは
<?php// 在 <?php 前有个空格
また、添付されたスクリプトまたはスクリプト ブロックに表示される場合もあります:
?><?php
PHP は終了タグの後に改行を占有しますが、その上には改行を挿入しません。タブ、または空白スペースにスペースを入れます(これは私たち自身の責任であることを意味します)。
-
UTF-8 BOM
改行やスペースは問題を引き起こす可能性がありますが、目に見えない文字シーケンスも問題を引き起こす可能性があります。最も有名なものは UTF-8 BOM で、ほとんどのテキスト エディターでは表示されません。これは、UTF-8 でエンコードされたドキュメント内のオプションまたは冗長バイト シーケンスであり、EF BB BF としてマークされます。ただし、PHP はそれを生の出力として扱う必要があります。 â で終わる場合もあります このような記号出力 (クライアントが文書を Latin-1 として解釈する場合) またはその他の「不正な出力」。
以某种图形化的编辑器或者基于 JAVA 的 IDE 查看这类文件时,你可能察觉不到 UTF-8 BOM 的存在。它们没有把 UTF-8 BOM 形象化(受制于 Unicode 标准)。然而大多数程序编辑器和控制台编辑程序会这样处理:
像这样就能简单地提早发现问题了。其他的编辑器在设置某些选项后也能纠正这样的问题(Windows 上的 Notepad++ 可以识别并且 纠正 BOM 问题 ),另一个发现 BOM 的方法就是借助十六进制的编辑器。在 *nix 系统上,大都提供了 hexdump ,如果没有的话,其他图形化的变种也可以用来简化审计这些问题的步骤:
一个简单的修正方法就是将文本编辑器设置为 以 UTF-8 (no BOM) 保存文件 ( save files as UTF-8 (no BOM) )或者其他类似的设置。
修正程序
有很多自动化的工具可以检测并修改文本文件( sed / awk 或者 recode )。PHP 里有 phptags 。它可以把打开标签和关闭标签重写成长标签(
phptags --whitespace *.php
同样,你可以在某个目录或整个项目目录使用这个命令。
-
?> 后的空白
如果错误代码在闭合标签 >? 这一行的前面,那么这就是 >? 后的空格或者原始文本输出导致的问题。PHP 的结束标记并不会在遇到闭合标签时终止执行脚本,任何 ?> 之后的文本或者空格字符都会被当作页面内容输出。
通用的被鼓励的做法,特别是针对新手,是避免在 PHP 文件后加上闭合标签 ?> 。这样就能避免一部分产生这类问题的情况。
-
错误源提示:”Unknown on line 0”
如果没有给出具体的错误源,那么这就是典型的 PHP 扩展或者 php.ini 设置的问题:
- 偶尔是 gzip 编码设置或者是 ob_gzhandler
- 也有可能是 php.ini 设置里模块加载了两次导致 PHP 产生了启动 / 警告信息
-
先前的错误导致输出了错误信息
如果前面的 PHP 语句或者表达式造成了 warning 或者 notice 信息导致输出,这些输出也被认为是过早地输出。
在这种情况下你需要避免错误,推后这些语句的执行,或者抑制这些信息的输出,可以使用 isset() 进行判断,或者使用抑制符 @ ,前提是它们不会阻止后续的调试。
没有错误信息输出
如果你禁用了 php.ini 里的 error_reporting 或者 display_errors 设置,那么将不会产生 warning 。但是忽略错误并不会让问题消失,头信息仍然不能在过早的输出输出之前发送出去。
所以当 header("Location: ...") 跳转静默地失败时,建议你去查看 warnings 。在脚本的最前面用下面的两条命令重新开启错误报告设置:
error_reporting(E_ALL);ini_set("display_errors", 1);
或者如果其他的设置都失败了那就设置 set_error_handler("var_dump"); 。
至于跳转的 header ,在执行至最后的代码时你应该遵循下面的这种风格:
exit(header("Location: /finished.html"));
最好是提供一个方法,特别是当 header() 执行失败时打印出用户信息。
变通方法:输出缓冲
PHP 的输出缓冲的方法是缓解这种问题的一种变通方法。它运行起来可靠,但是你绝不要使用它来替代你架构良好应用程序结构,从控制逻辑中分离输出。它的真实目的是用来减轻大块数据传输至服务器时的压力。
- output_buffering 设置 在 php.ini 或者 .htaccess 或者甚至在最新的 FPM/FastCGI 的 .user.ini 中设置;
- 同样你可以在脚本的最前面使用 ob_start() 来设置,但是它并没那么可靠:
- 即使 在第一个脚本里,空格或者 BOM 也有可能在此之前被输出
- 它可以隐藏 HTML 输出里的空格(将空格放到 buffer 中),但是只要应用程序逻辑企图发送二进制内容(比如生成的图片),缓冲里的无关的输出就会成为问题(这样 ob_clean() 方法就成为下一步的变通方法了)。
- 缓冲有大小限制,并且在默认配置下很容易超出,并且这种情况并不少见,一旦发生也不太容易追踪。
因此这两个方法变得不可靠了,特别是当你需要更改开发环境或者生产环境的配置的时候。这就是为什么输出缓冲被认为只是一种蹩脚的变通方法。
建议参考官方手册里的基本 使用方法 ,以及它的优缺点:
- 输出缓冲是什么
- 为什么使用 output buffering
- 使用输出缓冲是不好的实践吗?
- 正确使用 output buffering 解决 “header already sent” 的例子
但是在其他的服务器上是好的?
如果你之前没有收到过头信息的 warning ,那么 php.ini 里的 output_buffering 设置改变了。在现在的/不同的服务器上很有可能没有设置。
使用 headers_sent() 检查
你可以使用 headers_sent 来检查是否可以发送头信息。这种方法可以有效地检查以便输出一个错误信息或是应用其他的逻辑。
不错的回退变通方法有:
-
HTML tag
如果你的应用程序很难在结构上解决这个问题,有个简单但显得不专业的做法是在 HTML
标签中来跳转网页。可以这样实现:
<meta http-equiv="Location" content="http://example.com/">
或者加上一个延迟时间
<meta http-equiv="Refresh" content="2; url=../target.html">
-
JavaScript 跳转
另一个可选的方法就是使用 JavaScript 跳转 来实现网页跳转:
<script> location.replace("target.html"); </script>
这种方式相比较
方法起来更兼容 HTML 标准,它只依赖于可以运行 JavaScript 的客户端。
这两种方式在 HTTP header() 调用失败时都提供了可以接受的回退方式。理想化的处理方式应该是将跳转与其它方式结合,给出对用户友好的辅助信息并且提供一个可点的链接以供后续操作。
为什么 setcookie() 和 session_start() 都会被影响
setcookie() 和 session_start() 都需要发送一个 set-cookie: 的 HTTP 头信息。这种情况就和前面输出 header() 的情况类似,所以同样会出现由于过早地输出错误信息导致的错误。
(当然它们受影响也有可能是因为客户端禁止了 cookie 导致的,设置可能是代理的问题。很明显,session 也取决去剩余磁盘空间大小或者 php.ini 里的其它设置)
原文链接: http://stackoverflow.com/questions/8028957/how-to-fix-headers-already-sent-error-in-php

PHPは、動的なWeb開発およびサーバー側のアプリケーションに使用されるサーバー側のスクリプト言語です。 1.PHPは、編集を必要とせず、迅速な発展に適した解釈言語です。 2。PHPコードはHTMLに組み込まれているため、Webページの開発が簡単になりました。 3。PHPプロセスサーバー側のロジック、HTML出力を生成し、ユーザーの相互作用とデータ処理をサポートします。 4。PHPは、データベースと対話し、プロセスフォームの送信、サーバー側のタスクを実行できます。

PHPは過去数十年にわたってネットワークを形成しており、Web開発において重要な役割を果たし続けます。 1)PHPは1994年に発信され、MySQLとのシームレスな統合により、開発者にとって最初の選択肢となっています。 2)コア関数には、動的なコンテンツの生成とデータベースとの統合が含まれ、ウェブサイトをリアルタイムで更新し、パーソナライズされた方法で表示できるようにします。 3)PHPの幅広いアプリケーションとエコシステムは、長期的な影響を促進していますが、バージョンの更新とセキュリティの課題にも直面しています。 4)PHP7のリリースなど、近年のパフォーマンスの改善により、現代の言語と競合できるようになりました。 5)将来的には、PHPはコンテナ化やマイクロサービスなどの新しい課題に対処する必要がありますが、その柔軟性とアクティブなコミュニティにより適応性があります。

PHPの中心的な利点には、学習の容易さ、強力なWeb開発サポート、豊富なライブラリとフレームワーク、高性能とスケーラビリティ、クロスプラットフォームの互換性、費用対効果が含まれます。 1)初心者に適した学習と使用が簡単。 2)Webサーバーとの適切な統合および複数のデータベースをサポートします。 3)Laravelなどの強力なフレームワークを持っています。 4)最適化を通じて高性能を達成できます。 5)複数のオペレーティングシステムをサポートします。 6)開発コストを削減するためのオープンソース。

PHPは死んでいません。 1)PHPコミュニティは、パフォーマンスとセキュリティの問題を積極的に解決し、PHP7.xはパフォーマンスを向上させます。 2)PHPは最新のWeb開発に適しており、大規模なWebサイトで広く使用されています。 3)PHPは学習しやすく、サーバーはうまく機能しますが、タイプシステムは静的言語ほど厳格ではありません。 4)PHPは、コンテンツ管理とeコマースの分野で依然として重要であり、エコシステムは進化し続けています。 5)OpcacheとAPCを介してパフォーマンスを最適化し、OOPと設計パターンを使用してコードの品質を向上させます。

PHPとPythonには独自の利点と短所があり、選択はプロジェクトの要件に依存します。 1)PHPは、Web開発に適しており、学習しやすく、豊富なコミュニティリソースですが、構文は十分に近代的ではなく、パフォーマンスとセキュリティに注意を払う必要があります。 2)Pythonは、簡潔な構文と学習が簡単なデータサイエンスと機械学習に適していますが、実行速度とメモリ管理にはボトルネックがあります。

PHPは動的なWebサイトを構築するために使用され、そのコア関数には次のものが含まれます。1。データベースに接続することにより、動的コンテンツを生成し、リアルタイムでWebページを生成します。 2。ユーザーのインタラクションを処理し、提出をフォームし、入力を確認し、操作に応答します。 3.セッションとユーザー認証を管理して、パーソナライズされたエクスペリエンスを提供します。 4.パフォーマンスを最適化し、ベストプラクティスに従って、ウェブサイトの効率とセキュリティを改善します。

PHPはMySQLIおよびPDO拡張機能を使用して、データベース操作とサーバー側のロジック処理で対話し、セッション管理などの関数を介してサーバー側のロジックを処理します。 1)MySQLIまたはPDOを使用してデータベースに接続し、SQLクエリを実行します。 2)セッション管理およびその他の機能を通じて、HTTPリクエストとユーザーステータスを処理します。 3)トランザクションを使用して、データベース操作の原子性を確保します。 4)SQLインジェクションを防ぎ、例外処理とデバッグの閉鎖接続を使用します。 5)インデックスとキャッシュを通じてパフォーマンスを最適化し、読みやすいコードを書き、エラー処理を実行します。

PHPで前処理ステートメントとPDOを使用すると、SQL注入攻撃を効果的に防ぐことができます。 1)PDOを使用してデータベースに接続し、エラーモードを設定します。 2)準備方法を使用して前処理ステートメントを作成し、プレースホルダーを使用してデータを渡し、メソッドを実行します。 3)結果のクエリを処理し、コードのセキュリティとパフォーマンスを確保します。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

ドリームウィーバー CS6
ビジュアル Web 開発ツール

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

Dreamweaver Mac版
ビジュアル Web 開発ツール
