ZipArchive — это встроенный в PHP класс, предоставляющий интерфейс для работы с ZIP-архивами: их создания, чтения, извлечения и модификации.
Он входит в расширение php-zip, которое обычно предустановлено (или устанавливается через sudo apt install php-zip).
Что делает ZipArchive
ZipArchive позволяет:
- 📦 Открывать ZIP-файлы (
open()). - 📂 Извлекать файлы (
extractTo()). - ➕ Добавлять новые файлы (
addFile(),addFromString()). - 🗑️ Удалять или переименовывать файлы внутри архива.
- 🚪 Закрывать архив (
close()), чтобы сохранить изменения.
Пример базового использования.
Извлечение архива.
use ZipArchive;
$zip = new ZipArchive();
$path = '/path/to/my-plugin.zip';
if ($zip->open($path) === TRUE) {
$zip->extractTo('/tmp/my-plugin');
$zip->close();
echo "✅ Архив успешно распакован";
} else {
echo "❌ Ошибка открытия архива";
}
Создание архива.
$zip = new ZipArchive();
$path = '/path/to/new-archive.zip';
if ($zip->open($path, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
$zip->addFile('/path/to/file1.php', 'file1.php');
$zip->addFile('/path/to/file2.txt', 'docs/file2.txt');
$zip->close();
echo "✅ Архив создан";
}
Мой пример: распаковка архива плагина чтобы узнать его версию.
class CreatePlugin extends CreateRecord
{
protected function afterCreate(): void
{
$record = $this->record;
$path = Storage::disk('local')->path($record->zip_path);
$zip = new ZipArchive();
if ($zip->open($path) !== true) {
Log::error("[PluginVersion] ❌ Cannot open ZIP at {$path}");
return;
}
$tempDir = storage_path('app/private/temp-plugins/temp_plugin_' . uniqid());
mkdir($tempDir, 0777, true);
$zip->extractTo($tempDir);
$zip->close();
$version = null;
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($tempDir, FilesystemIterator::SKIP_DOTS)
);
foreach ($iterator as $file) {
if ($file->isFile() && str_ends_with($file->getFilename(), '.php')) {
$contents = @file_get_contents($file->getPathname());
if (preg_match('/^[\s\/*#@]*Version:\s*([0-9A-Za-z.\-]+)/mi', $contents, $matches)) {
$version = trim($matches[1]);
Log::info("[PluginVersion] 🏷️ Found version '{$version}' in {$file->getPathname()}");
break;
}
}
}
if ($version) {
$record->update(['version' => $version]);
Log::info("[PluginVersion] ✅ Saved version {$version} for plugin ID={$record->id}");
} else {
Log::warning("[PluginVersion] ⚠️ No version found for plugin ID={$record->id}");
}
$deleteDir = function ($dir) use (&$deleteDir) {
if (!is_dir($dir)) return;
foreach (array_diff(scandir($dir), ['.', '..']) as $item) {
$path = "$dir/$item";
is_dir($path) ? $deleteDir($path) : unlink($path);
}
rmdir($dir);
};
$deleteDir($tempDir);
}
}
Что происходит по шагам:
- Открывается архив по пути
$path. - Создаётся временная директория
$tempDir. - Все файлы распаковываются в неё.
- Архив закрывается.
После этого ты можешь рекурсивно пройтись по $tempDir и анализировать содержимое плагина — искать Version:, Plugin Name: и т.д.