最近收到了一个需求,需要将很多文件导出为压缩文件,刚开始以为需要先一层一层将目录创建好,把对应文件放进去,然后利用压缩类对大文件夹整体压缩,后面发现没这么复杂,CI的read_file方法直接将文件读取进指定位置就可以了,然后download下载之后就是你想要的层级结构。
实践之后遇到了一个问题,阿里云oss的文件没法直接写入到压缩文件,可能是读取不到吧,因为本地文件是可以直接写入的。在网上没找到解决方法,想了一下,干脆将文件先写入本地,然后从本地写入压缩文件吧,问题又来了,常用的file_get_contents和file_put_contents没法将oss文件写入到本地,可能我技术不精,换个姿势使用curl读取,成功了,问题解决。下面是实现方式。。。没有去深究,如果有大神帮我解答原因,十分感激。
$cur_encoding = iconv_get_encoding(); //获取当前iconv的编码,方便后面转换
$this->load->library('zip');
foreach ($attach_file as $v){
$extend2 = strtolower(strrchr($v['url'], '.')); //获取后缀
//---------使用curl将文件写入本地
$ch = curl_init($v['url']);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$rawdata = curl_exec ($ch);
curl_close ($ch);
$fp = fopen(APPPATH.'cache/tmpdocx/a'.$extend2,'w'); //fopen的第一个参数,如果指定目录的话,目录如果不存在,将不会写入成功。也可以直接放在根目录下,反正这个文件只是一个临时文件,在写入压缩文件后还是会删除的。
fwrite($fp, $rawdata);
fclose($fp);
//----------写入完毕。
$dir_name = $dir_title.'/任务书/';
$dir_name = iconv ( $cur_encoding['input_encoding'], 'GBK', $dir_name); //这里是确保文件名编码支持中文,用iconv转为GBK
$file_name = iconv($cur_encoding['input_encoding'],'GBK',$v['name']);
//用read_file写入压缩问价,第一个参数就是前面利用curl写入的本地文件,第二个参数是目标位置,支持层级,也就是压缩文件里面对应的目录层级。
$this->zip->read_file(APPPATH.'cache/tmpdocx/a'.$extend2,$dir_name.$file_name);
//删除curl生成的临时文件。
unlink(APPPATH.'cache/tmpdocx/a'.$extend2);
}
//所有文件写入压缩文件之后,导出,浏览器会自动下载。
$this->zip->download('资料.zip');