Table Of Contents
The Solution
ZIP file operations provide essential functionality for file compression and archiving. PHP's ZipArchive class handles both creation and extraction efficiently.
<?php
// Create a ZIP archive
$zip = new ZipArchive();
$zipFile = 'archive.zip';
if ($zip->open($zipFile, ZipArchive::CREATE) === TRUE) {
// Add individual files
$zip->addFile('document.txt');
$zip->addFile('image.jpg', 'photos/image.jpg'); // With custom path
// Add string content directly
$zip->addFromString('readme.txt', 'This is the readme content');
// Add entire directory
addDirectoryToZip($zip, 'source_folder/', 'archive_folder/');
$zip->close();
echo "ZIP archive created successfully!\n";
} else {
echo "Cannot create ZIP archive\n";
}
// Function to add directory recursively
function addDirectoryToZip(ZipArchive $zip, string $sourceDir, string $zipPath = ''): void {
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($sourceDir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $file) {
$filePath = $file->getRealPath();
$relativePath = $zipPath . substr($filePath, strlen(realpath($sourceDir)) + 1);
if ($file->isFile()) {
$zip->addFile($filePath, $relativePath);
}
}
}
// Extract ZIP archive
function extractZipArchive(string $zipFile, string $extractTo): bool {
$zip = new ZipArchive();
if ($zip->open($zipFile) === TRUE) {
// Create extraction directory if it doesn't exist
if (!is_dir($extractTo)) {
mkdir($extractTo, 0755, true);
}
$zip->extractTo($extractTo);
$zip->close();
return true;
}
return false;
}
// Advanced ZIP creation with options
function createAdvancedZip(array $files, string $zipFile, array $options = []): array {
$zip = new ZipArchive();
$result = ['success' => false, 'errors' => []];
$flags = ZipArchive::CREATE | ZipArchive::OVERWRITE;
if ($zip->open($zipFile, $flags) !== TRUE) {
$result['errors'][] = "Cannot create ZIP file: $zipFile";
return $result;
}
foreach ($files as $file) {
$sourcePath = $file['source'];
$zipPath = $file['destination'] ?? basename($sourcePath);
if (!file_exists($sourcePath)) {
$result['errors'][] = "File not found: $sourcePath";
continue;
}
if (is_file($sourcePath)) {
if (!$zip->addFile($sourcePath, $zipPath)) {
$result['errors'][] = "Failed to add file: $sourcePath";
}
} elseif (is_dir($sourcePath)) {
addDirectoryToZip($zip, $sourcePath, $zipPath);
}
}
// Set compression method if specified
if (isset($options['compression'])) {
for ($i = 0; $i < $zip->numFiles; $i++) {
$zip->setCompressionIndex($i, $options['compression']);
}
}
$zip->close();
$result['success'] = true;
return $result;
}
// Selective extraction
function extractZipSelectively(string $zipFile, array $filesToExtract, string $extractTo): array {
$zip = new ZipArchive();
$result = ['extracted' => [], 'errors' => []];
if ($zip->open($zipFile) !== TRUE) {
$result['errors'][] = "Cannot open ZIP file: $zipFile";
return $result;
}
if (!is_dir($extractTo)) {
mkdir($extractTo, 0755, true);
}
foreach ($filesToExtract as $fileName) {
$fileContent = $zip->getFromName($fileName);
if ($fileContent === false) {
$result['errors'][] = "File not found in archive: $fileName";
continue;
}
$outputPath = $extractTo . DIRECTORY_SEPARATOR . $fileName;
// Create directory structure if needed
$outputDir = dirname($outputPath);
if (!is_dir($outputDir)) {
mkdir($outputDir, 0755, true);
}
if (file_put_contents($outputPath, $fileContent) !== false) {
$result['extracted'][] = $fileName;
} else {
$result['errors'][] = "Failed to extract: $fileName";
}
}
$zip->close();
return $result;
}
// List ZIP contents
function listZipContents(string $zipFile): array {
$zip = new ZipArchive();
$contents = [];
if ($zip->open($zipFile) === TRUE) {
for ($i = 0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex($i);
$contents[] = [
'name' => $stat['name'],
'size' => $stat['size'],
'compressed_size' => $stat['comp_size'],
'compression_method' => $stat['comp_method'],
'modified' => date('Y-m-d H:i:s', $stat['mtime'])
];
}
$zip->close();
}
return $contents;
}
// Validate ZIP file
function validateZipFile(string $zipFile): array {
$zip = new ZipArchive();
$validation = ['valid' => false, 'errors' => []];
$result = $zip->open($zipFile, ZipArchive::CHECKCONS);
if ($result === TRUE) {
$validation['valid'] = true;
$validation['file_count'] = $zip->numFiles;
$zip->close();
} else {
$validation['errors'][] = match($result) {
ZipArchive::ER_NOZIP => 'Not a ZIP archive',
ZipArchive::ER_INCONS => 'ZIP archive inconsistent',
ZipArchive::ER_CRC => 'CRC error',
ZipArchive::ER_OPEN => 'Cannot open file',
default => 'Unknown ZIP error: ' . $result
};
}
return $validation;
}
// Usage examples
try {
// Create backup ZIP
$filesToBackup = [
['source' => 'config/', 'destination' => 'config/'],
['source' => 'data.json', 'destination' => 'data.json'],
['source' => 'logs/', 'destination' => 'logs/']
];
$backupResult = createAdvancedZip($filesToBackup, 'backup.zip', [
'compression' => ZipArchive::CM_DEFLATE
]);
if ($backupResult['success']) {
echo "Backup created successfully\n";
} else {
echo "Backup errors: " . implode(', ', $backupResult['errors']) . "\n";
}
// Validate ZIP file
$validation = validateZipFile('backup.zip');
if ($validation['valid']) {
echo "ZIP file is valid, contains {$validation['file_count']} files\n";
}
// List ZIP contents
$contents = listZipContents('backup.zip');
foreach ($contents as $file) {
echo "File: {$file['name']} ({$file['size']} bytes)\n";
}
// Extract specific files
$extractResult = extractZipSelectively('backup.zip', ['config/app.php', 'data.json'], 'restore/');
echo "Extracted: " . implode(', ', $extractResult['extracted']) . "\n";
// Full extraction
if (extractZipArchive('backup.zip', 'full_restore/')) {
echo "Full extraction completed\n";
}
} catch (Exception $e) {
echo "ZIP operation error: " . $e->getMessage() . "\n";
}
Why This Works
The ZipArchive class provides comprehensive ZIP file handling capabilities through a simple API. It supports both creation and extraction operations with fine-grained control over compression methods, file paths, and selective operations.
Key advantages include memory-efficient processing for large archives, support for password protection, and the ability to work with files without extracting the entire archive. The class handles the complex ZIP format specifications automatically while providing access to metadata like compression ratios and modification times.
Perfect for backup systems, file distribution, data archival, and any application requiring compressed file storage or transfer.
Add Comment
No comments yet. Be the first to comment!