Implementing File Zipping and Download in PHP with ThinkPHP6
This tutorial explains how to set up a Windows development environment, install the ThinkPHP6 framework, and create a PHP class that compresses files or directories into a ZIP archive, optionally streams it for download, and also provides a method for extracting ZIP files.
The article provides a step‑by‑step guide for building a PHP utility that compresses files or folders into a ZIP archive and optionally streams the archive for download, using the ThinkPHP6 framework and Composer.
Environment : Windows 10 x64, phpstudy as the integrated PHP environment, and Composer for dependency management.
Install ThinkPHP6 with the following command: composer create-project topthink/think tp6 Zipdown class – the core of the solution includes three public methods:
<?php
namespace Jrk;
class Zipdown {
/**
* Create a ZIP archive from files or a directory.
*/
public function zip_file($files = [], $zipName = '', $wen = true, $isDown = true) {
$zip_file_path = 'zip/';
if (empty($zipName)) {
$zipName = $zip_file_path . date('YmdHis') . '.zip';
} else {
$zipName = $zip_file_path . $zipName . '.zip';
}
$zip = new \ZipArchive;
if ($zip->open($zipName, \ZIPARCHIVE::OVERWRITE | \ZIPARCHIVE::CREATE) !== true) {
exit('Unable to open or create ZIP file');
}
if (is_string($files)) {
$this->addFileToZip($files, $zip);
} else {
foreach ($files as $val) {
if (file_exists(app()->getRootPath() . 'public' . $val['att_dir'])) {
if ($wen) {
$zip->addFile(app()->getRootPath() . 'public' . $val['att_dir'], iconv('UTF-8','gbk',$val['img_dir'].'/'.$val['name']));
} else {
$zip->addFile(app()->getRootPath() . 'public' . $val['att_dir'], iconv('UTF-8','gbk',$val['name']));
}
}
}
}
$zip->close();
if (!file_exists($zipName)) {
exit('File does not exist');
}
if ($isDown) {
header('Cache-Control: public');
header('Content-Description: File Transfer');
header('Content-disposition: attachment; filename=' . basename($zipName));
header('Content-Type: application/zip');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($zipName));
@readfile($zipName);
@unlink(app()->getRootPath() . 'public/' . $zipName);
} else {
return $zipName;
}
}
/**
* Recursively add files from a directory to the ZIP archive.
*/
public function addFileToZip($path, $zip) {
$handler = opendir($path);
while (($filename = readdir($handler)) !== false) {
if ($filename != '.' && $filename != '..') {
$filename = iconv('gb2312','utf-8',$filename);
if (is_dir($path . '/' . $filename)) {
$this->addFileToZip($path . '/' . $filename, $zip);
} else {
$file_path = $path . '/' . $filename;
$zip->addFile($file_path, basename($file_path));
}
}
}
@closedir($path);
}
/**
* Extract a ZIP archive to a specified directory.
*/
public function unzip_file($file, $dirname) {
if (!file_exists($file)) {
return false;
}
$zipArc = new \ZipArchive();
if (!$zipArc->open($file)) {
return false;
}
if (!$zipArc->extractTo($dirname)) {
$zipArc->close();
return false;
}
return $zipArc->close();
}
}
?>Usage example – a controller method that obtains file IDs, fetches the corresponding records, creates a Zipdown instance, and triggers the download:
public function download() {
$id = $this->request->param('id');
if (is_array($id)) {
$ids = $id;
} else {
$ids = explode(',', $id);
}
$data = $this->model->where('id','in',$ids)->select()->toArray();
if (empty($data)) {
$this->error('No data available');
}
$zip = new Jrk\Zipdown();
$zip->zip_file($data);
}The author reports that the implementation has been tested and works reliably for packaging and downloading files or directories as ZIP archives.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
php Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
