Cannot modify header information
在将部分旧文章的网址301跳转到指定网址时,出现如下错误:
Warning: Cannot modify header information - headers already sent by (output started at header.php:65) in 404.php on line 76
出错的原因原因是在php程序里使用了如下代码做301跳转:
//添加301状态码
header("HTTP/1.1 301 Moved Permanently");
//跳转页面
header('Location:https://www.diyidaima.com'.$details_page);
也就是说,在执行修改或发送Http header的函数之前,不能够有任何的输出,否则会报如上错误。
因为 header()发送之前不能有任何输出,空格也不行,你需要将header()之前的空格去掉,或者其他输出的东西去掉,如果他上面include其他文件了,你还要检查其他文件里是否有输出。
解决方法可以按照以下步骤解决:
1.查看php.ini的配置
找到php.ini文件中的output_buffering,默认为off的,把它改为on或者任意一个数字,如4096,即output_buffering = 4096,如果已经默认开启或者开启还是解决不了,看下一步。
2.使用ob_start()函数和ob_end_flush()
ob_start()函数用于打开缓冲区,比如header()函数之前如果就有输出,包括回车空格换行都会有”Header had all ready send by”的错误,这时可以先用ob_start()打开缓冲区PHP代码的数据块和echo()输出都会进入缓冲区而不会立刻输出。
通过以下方法,问题可以得到解决:
//打开缓冲区
ob_start();
//输出
echo "第一代码";
//把浏览器重定向到首页
header('Location:https://www.diyidaima.com');
//输出全部内容到浏览器
ob_end_flush();
如果还是也不行,需要查看一下是否还有别的输出函数没有被ob_start()和ob_end_flush()包裹,这些输出函数有:
print, echo, printf, vprintf
trigger_error, ob_flush, ob_end_flush, var_dump, print_r
readfile, passthru, flush, imagepng, imagejpeg
如果有,可以将ob_start()位置上移。如果这样还解决不了,请看第3步。
3.问题定位
1)输出语句的位置
在发送http header之前使用了输出语句,有些输出语句比较隐蔽,这些输出的函数包括:
print, echo, printf, vprintf
trigger_error, ob_flush, ob_end_flush, var_dump, print_r
readfile, passthru, flush, imagepng, imagejpeg
这一步实际上在第2步已经执行,可以忽略。但是需要注意include文件里的输出语句。
2)原始HTML块
.php文件中未解析的HTML部分也是直接输出
<!DOCTYPE html>
<?php
// ....
3)<?php之前有空白字符
<?php之前的空白字符会导致输出。
<?php
# 在<?php之前存在空格
4)追加的php脚本换行也会导致
<?php
...
?>
<?php
...
?>
5)UTF-8 BOM
一些UTF-8 BOM字符我们是看不见的,如果在<?php之前存在也会导致输出,所有比较稳妥的方式是把.php文件保存为UTF-8 (no BOM)格式。
6)先前脚本的错误信息
如果前面的脚本存在错误信息,这样也会导致输出。如include其他文件了,你还要检查其他文件里是否有输出。