Create a Zip File in PHP

A zip file compresses and bundles multiple files into a single file. Learn how to store uploaded files in a ZipArchive with a working demo and source code. We will use the zip extension of PHP, which is included in PHP's default extensions bundle.

Create a Zip File in PHP

What is ZipArchive?

ZipArchive is a file format that allows us to compress and store multiple files into a single file. With ZipArchive, we can reduce the file size and easily share a single file. We can compress different file types with ZipArchive, such as text files, images, videos, and many others. Learn in this post how to create a zip file in PHP using the PHP ZipArchive class.

 

How to Create a Zip File in PHP (ZipArchive Class)

Creating a zip file in PHP is simple and easy. We create a user interface with HTML to upload files, submit the form to the server-side script, add uploaded files to a zip, and finally trigger the download of the zip file. Creating zip files in PHP can be divided into the following steps:

  • Create an HTML form interface to upload files.
  • Send the form data with submitted files to the server-side PHP script.
  • Validate file type and file size for each entry.
  • Compress files using the PHP ZipArchive class.
  • Trigger browser download of the zip archive.

To create a zip file in PHP, we are going to create the following files:

  • index.html: The HTML form to upload files for PHP zip file creation.
  • process-zip.php: PHP script code to create a zip file of uploaded files.
  • style.css: CSS styles of index.php.


Create an HTML Form to Upload Files for Zip File Creation

In our index.php, we create a form with a file file upload field. We will compress them on the server side and generate a zip archive that contains these uploaded files. For demo purposes, we will allow only images and text files.

index.html

<!DOCTYPE html>
<html>
<head>
<title>Create a Zip File in PHP - Demo</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<meta content="width=device-width, initial-scale=1, maximum-scale=1" name="viewport" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<link rel="stylesheet" href="css/style.css" />
</head>
<body>
<section class="section py-4">
<div class="container">
<form action="process-zip.php" method="POST" enctype="multipart/form-data">
<div class="row">
<div class="col-6">
<input type="file" class="file-input" name="zip_files[]" multiple="multiple"/>
</div>
<div class="col-6 text-right">
<button type="submit" class="btn btn-blue">
<i class="fa fa-upload"></i>
Upload
</button>
</div>
</div>
</form>
</div>
</section>
</body>
</html>
 

Create and Download a Zip Archive File in PHP (Server Side)

In our process-zip.php, we create a zip file of uploaded files. We load the PHP zip extension if it is not already loaded, and add uploaded files to the zip file. After the zip file is created, we initiate a download with PHP headers. This is how this script is working:

  • Check if there are any files uploaded.
  • Check if the PHP zip extension is loaded; if the extension is not loaded, then load the extension at runtime. Load zip.dll  for Windows and zip.so for Unix-based systems.
  • Create an instance of a zip file using the PHP ZipArchive class.
  • Set a filename for our zip file and a file path to store the zip file. Create an array of allowed file type extensions.
  • Create and open a zip file with create and overwrite flags.
  • Loop through all uploaded files and check if each file is less than 2MB in size and has the extension from the $allowed_files array.
  •  Add each file to the zip archive.
  • Close the zip archive instance.
  • Set PHP headers for download and initiate download for the zip file we created.
  • Finally, delete the file after downloading.

process-zip.php

<?php
if (!empty($_FILES)) {
// If zip extension is not loaded then load it in runtime
if (!extension_loaded('zip')) {
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
load_lib('zip.dll');
} else {
load_lib('zip.so');
}
}

// Initialize zip archive
$zip = new ZipArchive();
$filename = time() . '_zip_file.zip';
$zip_file = __DIR__ . '/' . $filename;
$allowed_files = ['pdf', 'jpg', 'jpeg', 'gif', 'png', 'txt'];

if ($zip->open($zip_file, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)) {

// Loop all files and add them to zip
for ($i = 0; $i < count($_FILES['zip_files']['name']); $i++) {
$extension = pathinfo($_FILES['zip_files']['name'][$i], PATHINFO_EXTENSION);
$file_size_kb = number_format($_FILES['zip_files']['size'][$i] / 1024, 2);

//If uploaded file type is in allowed filed types then add it to zip
if (in_array($extension, $allowed_files) && $file_size_kb < 2048 && $i <= 15) {
$zip->addFile($_FILES['zip_files']['tmp_name'][$i], $_FILES['zip_files']['name'][$i]);
}
}

$zip->close();
}

// If file exists then set download headers
if (file_exists($zip_file)) {
ob_start();

header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . $filename . '";');
header('Content-Length: ' . filesize($zip_file));

ob_clean();

readfile($zip_file);
unlink($zip_file);
}
}
 

Add CSS Styles For Zip Form Interface

Add CSS styles for the entire page and the file upload form.

style.css

* {
box-sizing: border-box;
}
html,body {
margin: 0;
padding: 0;
}
body {
background-color: #f6f6f6;
font-family: "Segoe UI", "Roboto", "Helvetica", sans-serif;
font-size: 15px;
font-weight: normal;
font-style: normal;
line-height: 1.5;
}
.container {
width: 100%;
max-width: 1140px;
margin-right: auto;
margin-left: auto;
padding-right: 15px;
padding-left: 15px;
}
.py-4 {
padding-top: 1rem;
padding-bottom: 1rem;
}
.text-right {
text-align: right;
}
.row {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin-right: -15px;
margin-left: -15px;
}
.col-6 {
width: 100%;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
-webkit-box-flex: 0;
-ms-flex: 0 0 50%;
flex: 0 0 50%;
max-width: 50%;
}
.btn {
display: inline-block;
padding: 5px 10px;
cursor: pointer;
font: inherit;
}
.btn-blue {
background-color: #006699;
border: 1px solid #2b7cab;
color: #ffffff;
}

We just created a downloadable zip archive that uses PHP's built-in ZipArchive class. Having this feature makes it easy to bundle multiple files into a single file. The code in this post can be further extended to add folder support and password protection.