运行脚本时,我会遇到如下错误:
警告:无法修改标题信息-标题已由第23行的/some/file.php中的/some/file.php中的(输出开始于/some/file.php:12)发送
错误消息中提到的行包含header()和setcookie()调用
这可能是什么原因?如何修复它
发送标题之前没有输出
在进行任何输出之前,必须调用发送/修改HTTP头的函数。
总结⇊
否则,调用将失败:
警告:无法修改标题信息-标题已发送(输出从脚本:行开始)
修改HTTP头的一些函数包括:
标题/标题_删除会话\u开始/会话\u重新生成\u idsetcookie/setrawcookie
输出可以是:
-
无意的:
之前的空格<;?php或之后的?>- UTF-8字节顺序标记
- 以前的错误消息或通知
-
故意的:
print,echo和其他产生输出的功能- 原始
<;html>前面的章节<;?phpcode
为什么会这样
要理解为什么在输出之前必须发送头,这是必要的
查看典型的HTTP
回答PHP脚本主要生成HTML内容,但也传递
Web服务器的HTTP/CGI头集:
HTTP/1.1 200正常
受支持:PHP/5.3.7
改变:接受编码
内容类型:text/html;字符集=utf-8
<;html>&书信电报;头>&书信电报;标题>;PHP页面输出页面</标题></头>;
<;车身>&书信电报;h1>;内容</h1>&书信电报;p>;接下来会有更多的输出…</p>;
及<;a href="/&引用&燃气轮机&书信电报;img src=内部图标延迟></a>;
页面/输出始终在标题之后。PHP必须通过
首先将标题发送到Web服务器。它只能这样做一次。
在双线中断之后,它再也不能修改它们了
当PHP收到第一个输出(print,echo,<;html>;)时,它将
刷新所有收集的标题。之后,它可以发送所有输出
它想要。但是发送更多的HTTP头是不可能的
如何找出过早输出发生的位置
标题()
查找问题原因:
警告:无法修改标题信息-标题已由发送
(输出开始于/www/usr2345/htdocs/auth.php:52)中的
/www/usr2345/htdocs/index.php,第100行
“这里”;第100行“;指头()调用失败的脚本
"输出从开始;括号内的注释更为重要。
它命名以前输出的源。在本例中,它是auth.php
和行52。这就是你必须寻找过早产出的地方
典型原因:
-
打印、回显
来自
print和echo语句的有意输出将终止发送HTTP头的机会。必须重新构造应用程序流以避免这种情况。使用函数
以及模板方案。确保header()调用发生在消息之前
都写出来了产生输出的函数包括
print,echo,printf,vprintftrigger\u error,ob\u flush,ob\u end\u flush,var\u dump,print\u rreadfile,passthru,flush,imagepng,imagejpeg
以及用户定义的功能
-
原始HTML区域
.php文件中未解析的HTML部分也是直接输出的。
必须注意将触发header()调用的脚本条件
在任何原始之前<;html>块<;!DOCTYPE html>; <;?php //对标题来说已经太晚了。使用模板方案将处理与输出逻辑分离
- 将表单处理代码置于脚本之上
- 使用临时字符串变量延迟消息
- 实际的输出逻辑和混合HTML输出应该紧跟在最后。
-
之前的空格<;?phpfor";script.php第1行;警告如果警告指的是输出内联
1,则通常是
开头前的前导空格、文本或HTML<;?phptoken<;?php #前面只有一个空格/换行符<;?-它已经封住了它。类似地,附加脚本或脚本节也会出现这种情况:
?>; <;?phpPHP实际上会在关闭标记后吃掉一个单个换行符。但不会
补偿多个换行符、制表符或空格移动到这些间隙中 -
UTF-8物料清单
换行符和空格本身就是一个问题。但也有",;无形的;
可能导致这种情况的字符序列。最著名的是
UTF-8 BOM(字节顺序标记)
大多数文本编辑器都不会显示它。它是字节序列EF BB BF,对于UTF-8编码的文档是可选的和冗余的。然而,PHP必须将其视为原始输出。它可能会在输出中显示为字符ï»(如果客户将文档解释为拉丁语-1)或类似的“;“垃圾”尤其是图形编辑器和基于Java的IDE,它们不知道它的功能
在场他们没有将其可视化(受Unicode标准的约束)。
但是,大多数程序员和控制台编辑器会:在那里,很容易在早期发现问题。其他编辑可能会识别
它出现在文件/设置菜单中(Windows上的记事本+)可以识别
解决问题),,
检查BOM存在的另一个选项是求助于hexeditor。
在*nix系统上,通常可以使用hexdump,
如果不是简化审计这些问题和其他问题的图形变体:一个简单的解决方法是将文本编辑器设置为将文件另存为;UTF-8(无物料清单)“;
或类似于这种命名法。通常新来者会以其他方式创建新文件,而只是复制&;将以前的代码粘贴回校正实用程序
也有自动工具来检查和重写文本文件
(sed/awk或recode)。
特别是对于PHP,有phptagstagtidier。
它将关闭和打开标记重写为长和短形式,但也很容易
修复了前导和尾随空格、Unicode和UTF-x BOM问题:phptag——空白*.php在整个include或project目录中使用是安全的
-
?>如果提到错误源是在
关闭?>
然后这就是一些空白或原始文本被写出的地方。
PHP结束标记不会在此时终止脚本执行。之后的任何文本/空格字符都将作为页面内容写出
还是人们通常建议,尤其是对于新手,跟踪
?>PHP
应该省略关闭标记。这避免了这些案例中的一小部分。
(通常情况下,include()d脚本是罪魁祸首。) -
错误源称为;第0行“未知”
如果没有错误源,它通常是一个PHP扩展或PHP.ini设置
它被具体化了- 有时是
gzip流编码设置
或者ob\u gzhandler - 但它也可以是任何双重加载的
扩展=模块
生成隐式PHP启动/警告消息。
- 有时是
-
前面的错误消息
如果另一个PHP语句或表达式导致警告消息或
请注意,打印出来时,这也算作过早输出在这种情况下,您需要避免错误,
延迟语句执行,或使用以下命令抑制消息:。
isset()或@()-
当任何一个都不妨碍以后的调试时
没有错误消息
如果根据php.ini禁用了错误报告或显示错误,
那么就不会出现任何警告。但是忽略错误并不能解决问题
离开在过早输出后仍无法发送标题
所以当标题(“Location:…”)以静默方式重定向f时