PHP-PHP下传文件却多出了UTF8的BOM的问题
我们需要从服务器下载一个二进制文件到客户端,服务器是Ngix,文件放在服务器上,用php处理下载请求,进行下发。现在发现的问题是下载的内容比原文件多出了三个字节的UTF8的BOM。
不知道是什么原因?
补充一下,使用的是PHP的CI框架。
代码如下:
$cur_rule_path = self::RULE_DB_ROOT_PATH . '/' . self::NEW_RULE_DB_VER . "/";
$cur_rule_name =self::RULE_DB_NAME;
$filename= $cur_rule_path . $cur_rule_name;
$handle = fopen ($filename, "rb");
if($handle != NULL)
{
header ("Content-Type: application/octet-stream");
header('Content-Disposition: attachment; filename="downloaded.db"');
}
else
{
header('HTTP/1.0 404 Not Found');
header("status: 404 Not Found");
echo "file:$filename not found";
exit(0);
}
$file_size = filesize($filename);
header("Content-Length:$file_size");
fseek($handle,SEEK_SET,0);
do
{
if(feof($handle))
break;
$data = fread($handle,4096);
if(count($data) > 0)
{
echo $data;
}
}while(true);
fclose ($handle);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我觉得很明显是因为那个php文件开头就有BOM……在php服务器看来BOM就是三个字节的字符,而且出现在<?php之前,所以服务器就把它当作是文档的一部分发出去了。后面其他echo的内容都跟在后面。加个ob_end_clean()就好了的原因也只是因为——把之前发出去的BOM手工清除掉了而已。
检测UTF-8编码中的BOM
shell> grep -r -I -l $'^xEFxBBxBF' /path
删除UTF-8编码中的BOM
shell> grep -r -I -l $'^xEFxBBxBF' /path | xargs sed -i 's/^xEFxBBxBF//;q'
用editplus之类的文本工具重新保存一下代码文件即可,需要先在editplus设置删除签名。可参考http://www.dedecms8.com/php_mysql/php_bc/2927.html
肯定是某个文件引入了BOM,建议使用UTF-8 批量检测BOM工具(下载地址:http://download.csdn.net/detail/tidelgl/3278007)检测一下。
有高手协助,找到解决方法了,需要在函数头中增加这两个函数
ob_end_clean();
ob_start();
就可以解决问题,网上找了一下,可能跟输出缓冲区有关系
封装了一个函数用来检测UTF8的BOM:
<?php
$basedir="."; //修改此行为需要检测的目录,点表示当前目录
$auto=1; //是否自动移除发现的BOM信息。1为是,0为否。
if ($dh = opendir($basedir)) {
while (($file = readdir($dh)) !== false) {
if ($file!='.' && $file!='..' && !is_dir($basedir."/".$file)) echo "filename: $file ".checkBOM("$basedir/$file")." <br>";
}
closedir($dh);
}
function checkBOM ($filename) {
global $auto;
$contents=file_get_contents($filename);
$charset[1]=substr($contents, 0, 1);
$charset[2]=substr($contents, 1, 1);
$charset[3]=substr($contents, 2, 1);
if (ord($charset[1])==239 && ord($charset[2])==187 && ord($charset[3])==191) {
if ($auto==1) {
$rest=substr($contents, 3);
$filenum=fopen($filename,"w");
flock($filenum,LOCK_EX);
fwrite($filenum,$rest);
fclose($filenum);
return ("<font color=red>BOM found, automatically removed.</font>");
} else {
return ("<font color=red>BOM found.</font>");
}
}
else return ("BOM Not Found.");
}
?>