<?php
error_reporting(E_ALL);
ob_start("ob_gzhandler");//只要使用了它,后面的某些ob操作将导致问题
echo "content";
ob_end_clean();
ob_start();
ob_clean();
echo "more content";


firefox 12运行这上面的代码直接显示:

您尝试查看的页面无法显示,因为它使用了无效的或者不支持的压缩格式。


opera却能正常显示.


使用linux wget却也是正常的


root:/var/log/apache2# wget http://cms.china.net/temp_test.php                                            
--2012-05-22 23:44:42--  http://cms.china.net/temp_test.php                                                       
Resolving cms.chinahrd.net... 219.232.28.8                                                                         
Connecting to cms.chinahrd.net|219.232.28.58|:80... connected.                                                      
HTTP request sent, awaiting response... 200 OK                                                                       
Length: 12 [text/html]                                                                                               
Saving to: `temp_test.php'                                                                                           
                                                                                                                     
100%[===========================================================================>] 12          --.-K/s   in 0s       
                                                                                                                     
2012-05-22 23:44:43 (2.40 MB/s) - `temp_test.php' saved [12/12]                                                      
                                                                                                                     
root:/var/log/apache2# cat temp_test.php                                                                     
more contentroot:/var/log/apache2#

                                                          
                                                                                                                     
                                                
所以这应该是浏览解析的问题.肯定也是gzip处理后的问题导致.

最好的方法是不使用gzip,或是使用了就不要使用ob其它操作.


用话,有人建议这样用


ob_start("ob_gzhandler");echo("trashed");ob_end_clean();ob_start("ob_gzhandler");echo("output");ob_end_flush();


-------------------------开启gzip功能且能正常下载的代码,一般需要测试的文件是rar之类严格内容格式的文件类型,测试时可以使用------


function phpDown($file, $name = null){
    $file = str_replace(array('../', './'), '', $file);//不允许导致安全问题的路径出现,需要过滤./../
    
    if( file_exists($file) ){
        $path_parts = pathinfo($file);
        $size = filesize($file);
        if ($size < 1) exit('空白文件,不需要下载');
        $fileName = 'filename'.(strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox')>0 ? "*=\"utf8''" : '="') 
                    .rawurlencode($name ? $name.'.'.strtolower($path_parts["extension"]) : basename($file)).'"';//解决firfox与其它浏览处理中文名问题
        if(ob_get_length() !== false) @ob_end_clean();//尝试清除影响内容的前面输出
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');//任何文件类型都保存,非浏览
        header('Content-Disposition: attachment; ' .$fileName);
        header('Content-Encoding: none');//如果使用gzip将会导致问题,必须强制下载不使用压缩
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . $size);//给出大小
        readfile($file);
        exit;
    } else  die('File Not Found');
}

-----------------查看下载页面返回的全部内容:header与body,利用它可以看到浏览器怎么处理-------

<?php
header('Content-Type: text/html; charset=UTF-8');
var_dump(htm('/index.php?m=chrd&c=tooldown&a=down&aid=16170'));
/*
 * 从其它服务器请求htm,目的是方便修改,只需要修改一个htm多个页面变化
 */
function htm($file) {
    $incHost = 'cms.china.net';
    $htm = fsockopen($incHost, 80, $errno, $errstr, 30);
        
    if (!$htm) {
        return "$errno, $errstr";
    } else {
        $crlf = "\r\n";
        $get = "GET {$file} HTTP/1.1{$crlf}"
            ."Host: {$incHost}{$crlf}"
            ."Connection: Close{$crlf}"
            .$crlf;//表示提交结束了
        fwrite($htm, $get);
        $get = '';
        
        while (!feof($htm)) {
            $get .= fgets($htm, 128);
        }
        
        fclose($htm);
        
        return $get;
    }
}
-------

对于这个问题,网上很多人都只是说是php bug,经过测试应该不是,尝试了一天,误以为报头中编码这块只能设置编码,不能禁用.因为从浏览器中总是看到gzip,而使用上面的php查看返回头却是没有gzip报头的.导致rar格式有误的就是因为gzip报头影响只要处理掉它就基本上没事,这步是关键,对于清空缓存,这步,只是前面有输出时才是有必要的.那只是加了个保险


上面的问题在我测试时只出现在下面这个环境下

Apache Version     Apache/2.2.20 (Win32) PHP/5.3.3


而我在这个环境测试没有任何上面提到的问题.

PHP Version 5.4.0

Windows NT QIDIZI 6.1 build 7601 (Windows 7 Home Basic Edition Service Pack 1) i586

Apache/2.2.17 (Win32) PHP/5.4.0