最近做的项目中,涉及Linux下生成中文文件名并压缩打包下载乱码问题,需要将生成的压缩包文件自定义重命名(包括中文),问题来了,Linux下不支持中文的,所以会导致中文乱码问题,网上找了几天,都没解决,现在终于给码出来了,希望大家指出缺点。
首先,让linux支持中文,就是在/usr/lib/locale的默认中,添加以下三句,或者注释掉这三句前的#
zh_CN.GBK GBK
zh_CN.GB18030 GB18030
zh_CN.UTF-8 UTF-8
其次,由于下载的文件会把目录整个显示,之前转载别人的文章,
使用了pathinfo函数去获取他的basename,就避免了目录结构被暴露,
原来,文字编码中windows默认是GBK,而Linux默认是UTF-8,
这样就导致输出的是乱码,乱码的文字被自动忽略。
所以我重新写了一个pathinfo函数 path_info() 。
分享自己的code:
if($action == "downreport"){
if(substr($report_ids,-1)==","){
$report_ids = substr($report_ids,0,-1);
}
$report_id = $report_ids;
if($report_id == '0'){
die("{success:false,msg:'error',code:'e8000'}");
}
if(strpos($report_id,',')){
$arrids = explode(',',$report_id);
$newids = array();
foreach($arrids as $id){
$newids []= intval($id);
}
$ids = implodeids($newids);
$reports = array();
$reports_name = array();
$paths = array();
$query = $db->query("select `name`,filename from report_list where id in ($ids)");
while($report = $db->fetch_array($query)){
$reports[]= $report['filename'];
$reports_name[]= $report['name'];
}
for($i = 0; $i < count($reports); $i++ ){
$j = 1;
$temp_fileName = $reports_name[$i]."_";
while(file_exists(ESHINE_ROOT."tmp/temp/".$reports_name[$i] .".zip")){
$reports_name[$i] = $temp_fileName.$j;
$j++;
}
//$reports_name[$i] = $temp_fileName;
copy(ESHINE_ROOT."Report/".$reports[$i].".zip",ESHINE_ROOT."tmp/temp/".$reports_name[$i].".zip");
$paths[$i] = ESHINE_ROOT."tmp/temp/".$reports_name[$i].".zip";
}
//重写pathinfo函数,解决中文被置空 2014.11.26
function path_info($filepath)
{
$path_parts = array();
$path_parts ['dirname'] = rtrim(substr($filepath, 0, strrpos($filepath, '/')),"/")."/";
$path_parts ['basename'] = ltrim(substr($filepath, strrpos($filepath, '/')),"/");
$path_parts ['extension'] = substr(strrchr($filepath, '.'), 1);
$path_parts ['filename'] = ltrim(substr($path_parts ['basename'], 0, strrpos($path_parts ['basename'], '.')),"/");
return $path_parts;
}
//创建压缩包 2014.11.24
function create_zip($files=array(),$destination='',$overwrite=false){
//if the zip file already exists and overwrite is false, return false
//如果zip文件已经存在并且设置为不重写返回false
if(file_exists($destination) && !$overwrite){
return false;
}
$valid_files=array();
//获取到真实有效的文件名
if(is_array($files)){
//cycle through each file
foreach($files as $file){
//make sure the file exists
if(file_exists($file)){
$valid_files[]=$file;
}
}
}
//如果存在真实有效的文件
if(count($valid_files)){
//create the archive
$zip = new ZipArchive();
//打开文件 如果文件已经存在则覆盖,如果没有则创建
if($zip->open($destination,$overwrite?ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE)!==true){
return false;
}
//向压缩文件add the files
foreach($valid_files as $file){
//$zip->addFile($file,$file);
//$file_info_arr= pathinfo($file);
$file_info_arr = path_info($file);
$filename = $file_info_arr['basename'];
$filename = iconv('UTF-8', 'GBK//IGNORE', $filename);
//die($filename);
$zip->addFile($file,$filename);
}
$zip->close();
//check to make sure the file exists //检测文件是否存在
return file_exists($destination);
}else{
return false;
}
}
if(create_zip($paths,ESHINE_ROOT."tmp/temp/".$tempFileName.".zip",true)){
$newfiles = ESHINE_ROOT."tmp/temp/".$tempFileName.".zip";
}
//sleep(1);
$tempFileName = date("YmdHis",time()).mt_rand(1000, 9999);
for($i = 0; $i < count($paths); $i++ ){
@unlink($paths[$i]);
}
if(!$newfiles){
echo 'Not Found' . $newfiles;
exit;
}else{
header("Content-type: application/octet-stream");
//header("Content-type: application/force-download");
header("Accept-Ranges: bytes");
header("Accept-Length: ".filesize($newfiles));
header("Content-Disposition: attachment; filename=".$tempFileName.".zip");
//header('Content-Type: application/octet-stream; name=' . $out_filename);
touch($newfiles);
$file = fopen($newfiles, "r");
//echo fread($file, filesize($newfiles));
$buffer = 1024; //
//判断文件是否读完
while (!feof($file)) {
//将文件读入内存
$file_data = fread($file, $buffer);
//每次向客户端回送1024个字节的数据
echo $file_data;
}
fclose($file);
unlink($newfiles);
writelog($msg_download_log_reportlist.$newfiles);
}
}
}