I am working on a project which requires me to collect several files from the server, zip them, and mount the zip as a drive with js-dos.
Everything works ‘correctly’. During testing I manually made a zip file in windows and the code ran. For the final test I tried to mount the php generated zip but the folder structure is strange when doing DIR in js-dos.
I should have a single folder with several files in it. Instead there are several of the same folders with a single file inside.
The thing that breaks my brain is that when I open the file in winRAR it’s correct, but in js-dos it’s suddenly different.
Here is my code, it’s nothing fancy:
$rootPath = realpath($filefoldername."/"); $zip = new ZipArchive(); $zip->open($filefoldername.'/xp.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE); // Create recursive directory iterator /** @var SplFileInfo[] $files */ $filesZ = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($rootPath), RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($filesZ as $nameZ => $fileZ) { // Skip directories (they would be added automatically) if (!$fileZ->isDir()) { // Get real and relative path for current file $filePath = $fileZ->getRealPath(); $relativePath = substr($filePath, strlen($rootPath) + 1); // Add current file to archive $zip->addFile($filePath, $relativePath); } } // Zip archive will be created only after closing object $zip->close();
I’m guessing that windows over looks something that dos doesn’t. zip files made with winRAR are ok, but the ones generated by this code are strange.
I want to generate the .zip in php not by shell command. Can anyone help me figure this out?
Advertisement
Answer
Maybe js-dos cannot automatically create intermediate directories, you could try the code below to add intermediate directories to zip file.
$rootPath = realpath($filefoldername."/"); $zip = new ZipArchive(); $zip->open($filefoldername.'/xp.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE); // Create recursive directory iterator /** @var SplFileInfo[] $files */ $filesZ = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($rootPath), // !!!! replace LEAVES_ONLY with SELF_FIRST to include intermediate directories RecursiveIteratorIterator::SELF_FIRST ); foreach ($filesZ as $nameZ => $fileZ) { // Get real and relative path for current file $filePath = $fileZ->getRealPath(); $relativePath = substr($filePath, strlen($rootPath) + 1); $relativePath = str_replace('\', '/', $relativePath); if ($fileZ->isDir()) { $zip->addEmptyDir($relativePath); } else { $zip->addFile($filePath, $relativePath); } } // Zip archive will be created only after closing object $zip->close();