How to work with archives in PHP
Archive opening example:<?php ... $zip = new ZipArchive(); $archivePath = $archive->getPathname(); if (true !== $zip->open($archivePath)) { throw new \RuntimeException(sprintf('Cannot open archive "%s".', $archivePath)); } ...Archive files iterating example (without extracting):<?php ... /** @var ZipArchive $zip */ for ($i = 0; $i < $zip->numFiles; ++$i) { $fileName = $zip->getNameIndex($i); $stream = $zip->getStream($fileName); if ($stream) { $content = stream_get_contents($stream); // do something with content // if content is text - you can easily work with them! fclose($stream); } } ...Archive extracting & recursive files iterating (via RecursiveIteratorIterator and RecursiveDirectoryIterator) example:<?php ... // extraction $tempDir = sys_get_temp_dir() . sprintf('/%s', 'archive_') . uniqid('', true); if (false === @mkdir($tempDir, 0777, true) && !is_dir($tempDir)) { throw new RuntimeException(sprintf('Unable to create the "%s" directory.', $tempDir)); } $zip->extractTo($tempDir); $zip->close(); // iteration /** @var \SplFileInfo $file */ foreach ($filesFirstIterator as $file) { $pathName = $file->getPathname(); if ($file->isDir()) { // do something } if($file->isFile()) { // do domething } }And make sure that after any actions with extracted files you will delete temporary directory with the extracted archive. I suggest doing this in finally construction in case there is any error during your code work:<?php ... public function uploadArchiveAction(Request $request): Response { try { // your logic } catch (\Throwable $exception) { // do any actions } finally { $this->deleteDirectory($tempDir); } } private function deleteDirectory(string $dir): void { if (!is_dir($dir)) { return; } $filesFirst = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST ); foreach ($filesFirst as $file) { $pathName = $file->getPathname(); if ($file->isDir()) { rmdir($pathName); } else { unlink($pathName); } } rmdir($dir); }
1 месяц назад