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.

php Courses
php Courses
php Courses
Implementing File Zipping and Download in PHP with ThinkPHP6

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

File Downloadzip
php Courses
Written by

php Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.