ZipArchive "Error 21 is a directory" problem in PHP

I create a set of HTML, CSS and image files, and I use ZipArchive to compress them into a zip file. I have confirmed that the generated assets are valid, but when I try to fasten a set of files, the resulting archive file cannot be opened.

I get no errors in PHP, and when I echo $zip->close() , it returns true, which I suppose means that it was able to write and save the file without any problems. Opening zip with the Mac Archive Utility gives this error:

β€œUnable to deployβ€œ filename.zip ”toβ€œ Downloads. ”(Error 21 is a directory.)

What could be wrong here?

Here is the whole PHP script:

 <?php $ref = $_SERVER["HTTP_REFERER"]; $html = $_REQUEST['html']; $images = $_REQUEST['images']; $folder = uniqid(); $prepped = str_replace($ref.'server/php/files/', 'images/', $html); mkdir("./runways/$folder", 0777); mkdir("./runways/$folder/images", 0777); mkdir("./runways/$folder/css", 0777); file_put_contents('./runways/'.$folder.'/index.html',$prepped); copy('../../css/runway.css', './runways/'.$folder.'/css/runway.css'); foreach($images as $image) { $i = urldecode(str_replace($ref.'server/php/files/', '', $image)); $idata = file_get_contents('./files/'.$i); file_put_contents('./runways/'.$folder.'/images/'.$i, $idata); } //echo $ref.'server/php/runways/'.$folder.'/'; $sourcefolder = './runways/'.$folder.'/'; $zipfilename = $folder.'.zip'; $dirlist = new RecursiveDirectoryIterator($sourcefolder); $filelist = new RecursiveIteratorIterator($dirlist); ini_set('max_execution_time', 5000); $zip = new ZipArchive(); if ($zip->open('./zips/'.$zipfilename, ZIPARCHIVE::CREATE) !== TRUE) { die ("Could not open archive"); } foreach ($filelist as $key=>$value) { $zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key"); } $zip->close(); echo $ref.'server/php/zips/'.$zipfilename; ?> 
+6
source share
2 answers

The archive you create includes the current working directories and parent directories (file names "." And "..") that you must leave. For example, if you are viewing the contents of an archive created by source code, you will see something like this:

 $ unzip -l 54b69fbd2de29.zip Archive: 54b69fbd2de29.zip Length Date Time Name -------- ---- ---- ---- 0 01-14-15 09:56 ./runways/54b69fbd2de29/. 0 01-14-15 09:56 ./runways/54b69fbd2de29/.. 0 01-14-15 09:56 ./runways/54b69fbd2de29/css/. 0 01-14-15 09:56 ./runways/54b69fbd2de29/css/.. 12 01-14-15 09:56 ./runways/54b69fbd2de29/css/runway.css 0 01-14-15 09:56 ./runways/54b69fbd2de29/images/. 0 01-14-15 09:56 ./runways/54b69fbd2de29/images/.. 26 01-14-15 09:56 ./runways/54b69fbd2de29/images/image1.jpg 31 01-14-15 09:56 ./runways/54b69fbd2de29/images/image2.jpg 6 01-14-15 09:56 ./runways/54b69fbd2de29/index.html -------- ------- 75 10 files 

You do not want "./runways/54b69fbd2de29/." or "./runways/54b69fbd2de29/ .." etc. Here is one way to fix this, change the final foreach to the following (note also that you do not need $ key => $ value, just $ key):

 foreach ($filelist as $key) { if (!preg_match('/\/\.{1,2}$/',$key)){ $zip->addFile(realpath($key), $key) or die ("ERROR: Could not add file: $key"); } } 

The resulting archive is valid and looks like this:

 unzip -l 54b6a39d55a63.zip Archive: 54b6a39d55a63.zip Length Date Time Name -------- ---- ---- ---- 12 01-14-15 10:13 ./runways/54b6a39d55a63/css/runway.css 26 01-14-15 10:13 ./runways/54b6a39d55a63/images/image1.jpg 31 01-14-15 10:13 ./runways/54b6a39d55a63/images/image2.jpg 6 01-14-15 10:13 ./runways/54b6a39d55a63/index.html -------- ------- 75 4 files 
0
source

Small background: I chose to erase for my website and I uploaded public_html as a zip file. I was a little scared that I could not restore my site when it was reset.

A quick fix (and working for me) is an app from the App Store called The Unarchiver . I had the same problem when using a file compressed from cPanel file manager, and The Unarchiver seems to have fixed it.

0
source

Source: https://habr.com/ru/post/969611/


All Articles