欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

转 PHP_header location 使用注意事项

shiping1 的头像

PHP_header location 使用注意事项

发表于11个月前(2015-02-09 13:33)   阅读(244) | 评论(0) 4人收藏此文章, 我要收藏
0

header("Location:login.php")应该注意的几个问题 

header("Location:")作为php的转向语句。其实在使用中,他有几点需要注意的地方。

1、要求header前没有任何输出

但是很多时候在header前我们已经输出了好多东西了,此时如果再次header的话,显然是出错的,在这里我们启用了一个ob的概念,ob的意思是在服务器端先存储有关输出,等待适当的时机再输出,而不是像现在这样运行一句,输出一句,发现header语句就只能报错了。

具体的语句有: ob_start(); ob_end_clean();ob_flush();.........

2、在header("Location:")后要及时exit

否则他是会继续执行的,虽然在浏览器端你看不到相应的数据出现,但是如果你进行抓包分析的话,你就会看到下面的语句也是在执行的。而且被输送到了浏览器客户端,只不过是没有被浏览器执行为html而已(浏览器执行了header进行了转向操作)。

所以,标准的使用方法是:

ob_start();

........

if ( something ){

ob_end_clean();

header("Location: yourlocation");

exit;

else{

..........

ob_flush(); //可省略

 

要想在header前有输出的话,可以修改php.ini文件

output_handler =mb_output_handler

或 output_handler =on

 

Output Control 函数可以让你自由控制脚本中数据的输出。它非常地有用,特别是对于:当你想在数据已经输出后,再输出文件头的情况。输出控制函数不对使用 header() 或 setcookie(), 发送的文件头信息产生影响,只对那些类似于 echo() 和 PHP 代码的数据块有作用。

一、 相关函数简介:

1、Flush:刷新缓冲区的内容,输出。

函数格式:flush()

说明:这个函数经常使用,效率很高。

2、ob_start :打开输出缓冲区

函数格式:void ob_start(void)

说明:当缓冲区激活时,所有来自PHP程序的非文件头信息均不会发送,而是保存在内部缓冲区。为了输出缓冲区的内容,可以使用ob_end_flush()或flush()输出缓冲区的内容。

3 、ob_get_contents :返回内部缓冲区的内容。

使用方法:string ob_get_contents(void)

说明:这个函数会返回当前缓冲区中的内容,如果输出缓冲区没有激活,则返回 FALSE 。

4、ob_get_length:返回内部缓冲区的长度。

使用方法:int ob_get_length(void)

说明:这个函数会返回当前缓冲区中的长度;和ob_get_contents一样,如果输出缓冲区没有激活。则返回 FALSE。

5、ob_end_flush :发送内部缓冲区的内容到浏览器,并且关闭输出缓冲区。

使用方法:void ob_end_flush(void)

说明:这个函数发送输出缓冲区的内容(如果有的话)。

6、ob_end_clean:删除内部缓冲区的内容,并且关闭内部缓冲区

使用方法:void ob_end_clean(void)

说明:这个函数不会输出内部缓冲区的内容而是把它删除!

7、ob_implicit_flush:打开或关闭绝对刷新

使用方法:void ob_implicit_flush ([int flag])

说明:使用过Perl的人都知道$|=x的意义,这个字符串可以打开/关闭缓冲区,而ob_implicit_flush函数也和那个一样,默认为关闭缓冲区,打开绝对输出后,每个脚本输出都直接发送到浏览器,不再需要调用 flush()

 

 

ob_start() 开始输出缓冲, 这时PHP停止输出, 在这以后的输出都被转到一个内部的缓冲里.

ob_get_contents() 这个函数返回内部缓冲的内容. 这就等于把这些输出都变成了字符串.

ob_get_ length() 返回内部缓冲的长度.

ob_end_flush() 结束输出缓冲, 并输出缓冲里的内容. 在这以后的输出都是正常输出.

ob_end_clean() 结束输出缓冲, 并扔掉缓冲里的内容.

举个例子, var_dump()函数输出一个变量的结构和内容, 这在调试的时候很有用.

但如果变量的内容里有 < , > 等HTML的特殊字符, 输出到网页里就看不见了. 怎么办呢?

用输出缓冲函数能很容易的解决这个问题.

ob_start();

var_dump($var);

$out = ob_get_contents();

ob_end_clean();

这时var_dump()的输出已经存在 $out 里了. 你可以现在就输出:

echo '<pre>' . htmlspecialchars($out) . '</pre>' ;

或者等到将来, 再或者把这个字符串送到模板(Template)里再输出.



  •  0 关注
  •  2 收藏,4.4k 浏览
1

原文链接:PHP Header用于页面跳转要注意的几个问题总结php技巧脚本之家

搜到了这篇文章,开头就说了三个关于PHP header()的注意事项,

  1. location和“:”号间不能有空格,否则会出错。
  2. 在用header前不能有任何的输出。
  3. header后的PHP代码还会被执行。

第3点测试结果无误。

第1点,测试大概是指的 header('Location: http://segmentfault.com/'); 中 Location 和 : 不能有空格吧,但其实是可以有的。

主要是第2点,header前不能有任何的输出有疑问,我测试了下面的代码,能成功跳转啊:

<html>asdf</html>
<?php
header('Location : http://segmentfault.com/');

到底要怎样测试才能报错呢?php手册上的“Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP”到底是啥意思?

3 个回答

3
scaret 494 2014年01月06日 回答

header函数内的String原则上会被直接加到HTTP头里面去。所以说,如果发送

Location : http://with.blank.com

这种并不符合HTTP规范的HTTP头,很可能整个HTTP Response都无法解析。
幸运的是,PHP貌似为你修复了这个HTTP头格式问题。

关于HTTP头先发的问题,的确不应该在HTTP内容输出之后输出HTTP头。但是服务器会缓存输出,虽然你使用了echo或者print,但在那个时刻服务器还没有将这些内容作为HTTP报文输出,这个时候你仍然有机会修改HTTP头。

如果你只是单纯想要引发一个错误的话,很简单,在header()之前输出一个绝对超过缓存大小的HTTP内容就可以了。以下是不良示范。

<?php
  for($i = 0; $i < 1e5; $i++) echo $i;
  header("ABCABC: BCDBCD");
3
brayden 4.2k 2014年01月06日 回答 · 2014年01月07日 更新

@scaret 应该是对的, 其实就是缓存的问题.


<?php echo "<html></html>"; ob_flush(); flush(); header('Location: http://segmentfault.com/');

得到

Warning: Cannot modify header information - headers already sent by (output started at ...
2
Libo 825 2014年01月04日 回答 · 2014年01月04日 更新

你把html标签,换成PHP内部的echo,就会报错了。
php脚本中的html标签,其实是等整个PHP执行完,才会发送给用户的。
所以在你demo里面的header('Location : http://segmentfault.com/');前面,并没有任何输出。

header('Location : http://segmentfault.com/');这个方法,是在响应头里面,发一个302重定向。而响应头当然要比响应主体要提前输出。
详情可以用fiddler抓包看看

1

我试了好几次,不管在header前面或是后面输入内容,都能顺利跳转。。。。。。擦了,哪位大神给解释一下

#1 simon_zhao · 2014年01月04日 · 回复




来自 http://segmentfault.com/q/1010000000377390

普通分类: