file_get_contents下载网络文件问题

需求:把网络文件down到本地后,打包成zip文件后下载到客户端

测试的时候,使用的是百度到的图片地址,一切顺利。放到线上测试时,报错:function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.0 400 Bad request
百度后发现,可能是服务器对非浏览器访问有限制,需修改php.ini配置:user_agent=“Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)” 或者直接在file_get_contents前加上:ini_set(‘user_agent’,“Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)”);
修改后还是报错,但是文件能当下载下来,不过是错的,打不开。
后台想起来可能是文件名称编码的问题,因为文件中有中文,php的file函数在操作中文名称的文件时,需要转码。全部代码如下

function dlfile($file_url, $save_to)
{
    
    
    $file_url=iconv('utf-8','GBK',$file_url);//此处一定要使用GBK,而不是gb2312。因为gb2312只支持部分汉字,遇到繁体字或者生僻字时,就会转移失败,切记,避免入坑T_T都是类
    $content = file_get_contents($file_url);
    file_put_contents($save_to, $content);
}



 //多文件打包
$dir =  dirname(__FILE__);
$file_arr = [];
$fileList = array(
    "http://111.111.111/222/0000003812/王3152153.pdf",

);
foreach($fileList as $v){
    
    
    $ext = substr($v,strrpos($v,'.'));
    $file_name = time().rand('9999','1000000').$ext;
    $file_path = 'temp/'.$file_name;
    $file_arr[] = $file_name;
    dlfile($v,$file_path);
}
$filename = "test.zip";
$zip = new ZipArchive();
$zip->open($filename,ZipArchive::CREATE);   //打开压缩包
foreach($file_arr as $file){
    
    
    $zip->addFile($dir.'/temp/'.$file,$file);   //向压缩包中添加文件
}
$zip->close();

以上下载过程是把要下载的中文名文件转换成了字符串,此后的往zip打包下载都不会有问题。但是有时候,我们需要保留文件的中文名称,这样代码就需要做少许修改,如下

 //文件打包
$dir =  dirname(__FILE__);
$file_arr = [];
$fileList = array(
    "http://111.111.111/222/0000003812/王3152153.pdf",
    "http://111.111.111/222/0000003812/李3152153.pdf",
);
foreach($fileList as $v){
    
    
    $file_name = substr($v,strrpos($v,'/'+1));//保留文件的中文名
    $file_path = 'temp/'.$file_name;
    $file_path = iconv('utf-8','GBK',$file_path);//修改要保存文件的编码,win平台下需要该步骤。linux平台下不需要,因为linux平台编码默认为utf-8,与编辑器一直
    $file_arr[] = $file_name;
    dlfile($v,$file_path);
}
//中文名文件是无法直接添加到zip包中的,这里需要曲线救国
//第1步,先把下载到本地的文件改为英文字符串名,并建立中文名与英文名的对应关系数组
//第2步,把文件插入到zip包中
//第3步,使用zip类的更名函数,根据文件名对应关系数组,把文件名修改过来
//第4步,大功告成。如果你想把本地文件修改回中文名,一定要在close之后进行,否则zip会找不到文件

$filename = "test.zip";
$zip = new ZipArchive();
$zip->open($filename,ZipArchive::CREATE);   //打开压缩包
$file_r_name = [];//文件名对应关系数组
foreach($file_arr as $v){
    
    
	$ext = substr($v,strrpos($v,'.'));
	$new_name = time().substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'),0,10).rand(1000,100000).$ext;
	rename(iconv('utf-8','gb2312',ROOT_PATH.'public_html/baogao/'.$v),ROOT_PATH.'public_html/baogao/'.$new_name);
	$file_r_name[] = ['new_name'=>$new_name,'name'=>$v];
	//win平台下使用该步骤,linux下不需要要iconv,理由同上
}
$os_name=PHP_OS;//获取操作系统名称
foreach($file_r_name as $val){
    
    
	$zip->addFile(THINK_PATH.'../public_html/baogao/'.$val['new_name'],$val['new_name']);   //向压缩包中添加文件
	//修改压缩包中文件名修改为中文名
	if(strpos($os_name,"Linux")!==false){
    
    
         $zip->renameName($val['new_name'] , $val['name']);
     }elseif(strpos($os_name,"WIN")!==false){
    
    
     	 $zip->renameName($val['new_name'] , iconv('utf-8','GBK',$val['name']));
     }
}
$zip->close();

header('Location: http://www.kd.com/baogao/'.$filename);
exit;

猜你喜欢

转载自blog.csdn.net/u012830303/article/details/87936948