运行脚本时,我会遇到如下错误:
警告:无法修改标题信息-line 23上/some/file.php中的(output started at /some/file.php:12)已发送标题
错误消息中提到的线路包含header()
和setcookie()
个呼叫.
这可能是什么原因?如何修复它?
运行脚本时,我会遇到如下错误:
警告:无法修改标题信息-line 23上/some/file.php中的(output started at /some/file.php:12)已发送标题
错误消息中提到的线路包含header()
和setcookie()
个呼叫.
这可能是什么原因?如何修复它?
必须调用发送/修改HTTP头的函数101.
警告:无法修改标题信息-标题已发送(输出开始于脚本:行)
修改HTTP标头的一些功能包括:
输出可以是:
Unintentional:
<?php
之前或?>
之后的空格Intentional:
print
、echo
和其他产生输出的功能<html>
节之前的<?php
代码.要理解为什么在输出之前必须发送头,这是必要的
HTTP/1.1 200 OK
Powered-By: PHP/5.3.7
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
<html><head><title>PHP page output page</title></head>
<body><h1>Content</h1> <p>Some more output follows...</p>
and <a href="/"> <img src=internal-icon-delayed> </a>
页面/输出总是follows个页眉.PHP必须将 首先将标头发送到Web服务器.它只能这样做一次. 在双线之后,它再也不能修改它们了.
当PHP收到第一个输出(print
echo
<html>
)时,它将
header()
警告包含所有相关信息,以
找到问题原因:
警告:无法修改标题信息-标题已由发送
这里的"第header()
行"指的是header()
invocation失败的脚本.
括号内的"output started at"更重要.
Typical causes:
print
和echo
语句的有意输出将终止发送HTTP头的机会.必须对应用程序流进行重组以避免这种情况.使用functions
产生输出的函数包括
print
、echo
、printf
、vprintf
trigger_error
, ob_flush
, ob_end_flush
, var_dump
, print_r
readfile
, passthru
, flush
, imagepng
, imagejpeg
以及用户定义的函数.
.php
文件中未解析的HTML部分也是直接输出的.
<!DOCTYPE html>
<?php
// Too late for headers already.
使用模板方案将处理与输出逻辑分开.
<?php
for "script.php line 1" warnings如果警告指的是内联输出100,那么它主要是
开始<?php
令牌之前的前导whitespace、文本或HTML.
<?php
# There's a SINGLE space/newline before <? - Which already seals it.
类似地,附加脚本或脚本部分也会出现这种情况:
?>
<?php
PHP实际上会占用结束标记后的single个换行符.但它不会 补偿移入此类间隙的多个换行符、制表符或空格.
换行符和空格本身就是一个问题.但也有"看不见的"
特别是,图形编辑器和基于JAVA的IDE对于其 在场.他们没有将其可视化(受Unicode标准的约束). 但是,大多数程序员和控制台编辑器都是这样做的:
在那里,很容易在早期就认识到这个问题.其他编辑可能会指出
一个简单的解决方法是将文本编辑器设置为将文件保存为"UTF-8(无BOM)"
也有自动工具来判断和重写文本文件
phptags --whitespace *.php
在整个包含或项目目录中使用是安全的.
?>
如果错误源被称为
人们通常建议,尤其是对新手来说,使用?>
PHP
如果没有错误源,则通常是PHP扩展名或php.ini设置 是具体化的.
gzip
流编码设置extension=
module
generating an implicit PHP startup/warning message.如果其他PHP语句或表达式导致警告消息或 通知被打印出来,这也被算作过早输出.
在这种情况下,您需要避免错误,
延迟语句执行,或使用例如
isset()
或@()
-
当其中任何一个都不会妨碍以后的调试时.
如果您每php.ini
禁用error_reporting
或display_errors
,
那么就不会出现任何警告了.但是忽略错误并不能解决问题
离开.在过早输出之后,仍然无法发送标头.
因此,当header("Location: ...")
个重定向静默失败时,
建议调查警告.使用两个简单的命令重新启用它们
在调用脚本之上:
error_reporting(E_ALL);
ini_set("display_errors", 1);
如果其他方法都失败了,那就是set_error_handler("var_dump");
美元.
说到重定向头,你应该经常使用这样的习惯用法
exit(header("Location: /finished.html"));
优选地,甚至是打印用户消息的实用程序函数
在header()
次故障的情况下.
PHPs output buffering
The output_buffering=
setting nevertheless can help.
Configure it in the php.ini
or via .htaccess
or even .user.ini on
modern FPM/FastCGI setups.
Enabling it will allow PHP to buffer output instead of passing it to the webserver instantly. PHP thus can aggregate HTTP headers.
它同样可以拨打ob_start();
即使<?php ob_start(); ?>
开始第一个脚本,空格或
它可以隐藏HTML输出的空白.但一旦应用程序逻辑try 发送二进制内容(例如生成的图像),
缓冲区的大小有限,如果保留默认值,很容易溢出.
因此,这两种方法都可能变得不可靠——尤其是在两种方法之间切换时
如果你之前没有收到标题警告,那么output buffering php.ini setting
headers_sent()
如果出现以下情况,您始终可以使用headers_sent()
进行探测
仍然有可能...发送标题.它对有条件打印很有用
信息或应用其他后备逻辑.
if (headers_sent()) {
die("Redirect failed. Please click on this link: <a href=...>");
}
else{
exit(header("Location: /user.php"));
}
有用的备用解决方案包括:
<meta>
tag如果您的应用程序在 struct 上很难修复,那么简单的(但是
有些不专业)允许重定向的方法是注入HTML
<meta>
个标签.可以通过以下方式实现重定向:
<meta http-equiv="Location" content="http://example.com/">
或稍加延迟:
<meta http-equiv="Refresh" content="2; url=../target.html">
当使用超过<head>
节时,这会导致无效的HTML.
大多数浏览器仍然接受它.
作为替代方案,JavaScript重定向 可用于页面重定向:
<script> location.replace("target.html"); </script>
虽然这通常比<meta>
解决方法更符合HTML,
它会导致对支持JavaScript的客户端的依赖.
但是,当使用真正的HTTP Header()时,这两种方法都会产生可接受的后备 呼叫失败.理想情况下,您应该始终将其与用户友好的消息相结合,并且 作为最后手段的可点击链接.(例如,这就是http_redirect() PECL扩展可以.)
setcookie()
and session_start()
are also affectedsetcookie()
和session_start()
都需要发送Set-Cookie:
HTTP报头.
因此,适用相同的条件,并且将生成类似的错误消息
用于过早输出的情况.
(当然,他们还会受到浏览器中禁用的cookie的影响 甚至是委托书问题.会话功能显然也依赖于免费 磁盘空间和其他php.ini设置等)