2

I am trying to extract files from a zip file, but its failing with following error

Warning: copy(zip://upload/myzip-file.zip#myzip-file/file_001.csv): Failed to open stream: operation failed in {code line}

My file myzip-file.zip is placed inside upload folder, my code is able to read the contents of this file, but its unable to extract file one by one (I want to extract particular files only. I also want to avoid creation of sub folder)

$zip = new ZipArchive;
    if ($zip->open($zipPath) === true) {
        for($i = 0; $i < $zip->numFiles; $i++) {
            $filename = $zip->getNameIndex($i);
            $fileinfo = pathinfo($filename);
            copy("zip://".$zipPath."#".$filename, "my-path/".$fileinfo['basename']);
        }                  
        $zip->close();                  
    }

I suspect that copy functoin is not able to understand zip:// I found this sample on net where people have achived same using copy command but its not working for me any more.

Please note

  • My php script is at same location as are upload and my-path (All three in same directory)
  • My Zip does contain an extra folder myzip-file and its confirmed by extracting the full zip contentents and this sinppet $zip->getNameIndex($i); also revealed that.

Please note you don't have to fix it, but if have any sample which is extracting one single file from zip. It will work for me.

PHP Avenger
  • 1,744
  • 6
  • 37
  • 66

1 Answers1

0

I have tested your PHP script, it will work if

  • using relative path (so use $zipPath="./upload/myzip-file.zip"; and "./my-path/")
  • my-path is writable
  • over the iteration, better do not process the "file" if the $filename is actually a directory
  • so the directory structure is like the attached picture (myzip-file.zip is placed inside the upload folder, the process.php is the PHP to do the job)

So use the following code (I tested in a linux server and it works)

<?php

$zipPath="./upload/myzip-file.zip";

$zip = new ZipArchive;
    if ($zip->open($zipPath) === true) {
        for($i = 0; $i < $zip->numFiles; $i++) {
            $filename = $zip->getNameIndex($i);
            $fileinfo = pathinfo($filename);
      
          if (substr($filename, -1) !="/"){
            copy("zip://".$zipPath."#".$filename, "./my-path/".$fileinfo['basename']);
          }
        }                  
        $zip->close();                  
    }

?>

enter image description here

Ken Lee
  • 6,985
  • 3
  • 10
  • 29