首页 > 代码库 > php的header()函数前有echo输出情况分析

php的header()函数前有echo输出情况分析

  php的header()方法一般被用来告知浏览器做一些什么样的操作,比如跳转,刷新等等;而调用header方法前,如果使用echo输出一些内容,会发生什么情况呢?会对header函数有影响吗?我们实验来看看情况。

 

第一部分: 选择环境和版本

  我们的测试选择的是LNNP,php的版本是5.3.8,相对较老的版本

  技术分享

 

第二部分:测试用例

<?php$str  = "qwertyuiopasdfghjklzxcvbnm1234567890~!@#$%^&*()_+";$time = 10;   for ($i = 0; $i < $time; $i ++){  $x = rand(0, 40);  $v = substr($str, $x, 1);  echo $v;}header(‘Refresh:3, http://www.baidu.com‘); 

解释一下这个测试用例,

1、$time变量用来控制echo输出字符的大小

2、为什么用for循环输出乱序的字符?原因从第三部分抓包的情况可以看到,浏览器端一般要求response内容部分进行gzip压缩。而这个压缩实际上是php做的,为排除gzip压缩对实验影响,所以用for循环做乱序输出

 

第三部分:抓包分析

 1、正常情况,$time变量比较小的情况下

  1) 浏览器发送请求给Nginx

 技术分享

  

  2) nginx将请求包装后发送给php-fpm 技术分享

  

  3) php-fpm将结果回传nginx

 技术分享

 

  4) nginx将结果回传浏览器

 技术分享

 

2、异常情况,$time变量较大的情况下
    我们看1中第三步,php-fpm将结果回传nginx,我们发现两点
    1) 无法实现跳转。  从抓包的情况是php无法修改输出header头的信息,其原因应该是header信息,已经被write到socket fd中,缓存池中不存在header信息,所以无法修改
    2) echo输出的内容无影响。

技术分享

 

第四部分:分析和结论

       结合上面的情况,从第三部分的第一点,我们实际上可以看出,header函数的实现,实际上是把header函数的参数,作为字符串加到输出的返回内容 的header头部分,而在echo内容较大的时候,header头的字符串就无法输出了。

   我们可以看出php的处理过程    echo 的内容都会被放到缓存池内,当缓存池满的时候, 会将缓存池的内容write到socket fd内,一旦write进去,header函数将无法再把header字符串写到返回请求的header头部分。所以这种情况下,header函数将失效。

php的header()函数前有echo输出情况分析