前几天有这么个需求，以后可能也用的上，先保存下来。下载文件到指定目录/** * 下载文件到指定目录 * @param $file_url 请求下载的链接 * @param $path 保存位置 * @param string $save_name 文件名，留空使用下载来的文件名 * @return string 返回下载的文件路径 */ public function downloadFile($file_url, $path, $save_name = ''){ $basePath = DIR_ROOT."upfile/"; if($path){ $basePath .= $path."/"; } $dir_path = $basePath; if (!is_dir($dir_path)) { mkdir($dir_path, 0777, true); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $file_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); $file = curl_exec($ch); curl_close($ch); //传入保存文件的名称 $filename = $save_name ?: pathinfo($file_url, PATHINFO_BASENAME); $resource = fopen($dir_path. '/'. $filename, 'a'); fwrite($resource, $file); fclose($resource); return $basePath . '/' . $filename; }打包文件/** * 打包文件 * @param $path 需要打包的路径 * @param $zip ZipArchive对象 * @param string $child_path 递归子文件夹用的 */ public function addFileToZip($path, &$zip, $child_path = ''){ $handler = opendir($path); //打开当前文件夹由$path指定。 while(($filename=readdir($handler)) !== false){ if($filename != "." && $filename != ".."){ //文件夹文件名字为'.'和‘..'，不要对他们进行操作 if(is_dir($path."/".$filename)){ // 如果读取的某个对象是文件夹，则递归 $zip->addEmptyDir($filename); // 这里注意：php只需传递一个文件夹名称路径即可 $this->addFileToZip($path . "/" . $filename, $zip, $filename); }else{ //将文件加入zip对象 if (!empty($child_path)){ $zip->addFile($path."/".$filename, $child_path."/".$filename); } else{ $zip->addFile($path."/".$filename, $filename); } } } } @closedir($path); }{alert type="warning"}注意调用上面的打包方法时，需要先实例化ZipArchive对象，上示例:{/alert}// 下载到服务器后将文件夹打包为zip $outName = $this->datasheetBase->FormatJobCode($job_code_id).'.zip'; // 压缩包名称 $zipPath = DIR_ROOT."upfile/output/$outName"; // 导出的路径 if (file_exists($zipPath)) @unlink($zipPath); // 清理旧文件 $zip = new ZipArchive(); $data_file = DIR_ROOT."upfile/zip/".$this->customer->getID(); // 需要打包的路径 if ($zip->open($zipPath, ZipArchive::CREATE) === TRUE){ if (!is_dir($data_file)) mkdir($data_file); $this->datasheetBase->addFileToZip($data_file, $zip); } $zip->close();打包完成后，清理缓存文件。因为rmdir方法不能删除有文件的文件夹，所以需要先删除改文件夹的文件，再清理文件夹。上代码：/** * 清理文件 * @param $path */ public function clearFile($path){ $handler = opendir($path); while (($filename=readdir($handler)) !== false){ if($filename != "." && $filename != ".."){ //文件夹文件名字为'.'和‘..'，不要对他们进行操作 if(is_dir($path."/".$filename)){ // 删除文件夹底下的文件 $this->clearFile($path . "/" . $filename); }else{ @unlink("$path/$filename"); } } } @closedir($path); $this->removeDIR($path); } /** * 将缓存文件夹删除 * @param $path */ private function removeDIR($path){ $handler = opendir($path); while (($filename=readdir($handler)) !== false){ if($filename != "." && $filename != ".."){ //文件夹文件名字为'.'和‘..'，不要对他们进行操作 if(is_dir($path."/".$filename)){ @rmdir($path . "/" . $filename); // 删除文件夹 } } } @closedir($path); }最后重定向到打包好的文件就行header("Cache-Control: public"); header("Content-Description: File Transfer"); header('Content-disposition: attachment; filename='.$outName); // 文件名 header("Content-Type: application/zip"); header("Content-Transfer-Encoding: binary"); header('Content-Length: '. filesize($zipPath)); // 文件大小 header("Location:".HTTPS_SERVER."upfile/output/$outName");