Search code examples
phpcopyzip

File exists but getting warning of failed to open stream: No such file or directory


<?php
$arch_filename = "myzipx.zip";
$dest_dir = "./dest";
if (!is_dir($dest_dir)) {
    if (!mkdir($dest_dir, 0755, true))
        die("failed to make directory $dest_dir\n");
}
$zip = new ZipArchive;
if (!$zip->open($arch_filename))
    die("failed to open $arch_filename");

for ($i = 0; $i < $zip->numFiles; ++$i) {
    $path = $zip->getNameIndex($i);
    $ext = pathinfo($path, PATHINFO_EXTENSION);
    if (!preg_match('/(?:pdf)/i', $ext))
        continue;
    $dest_basename = pathinfo($path, PATHINFO_BASENAME);
    echo $path, PHP_EOL;

    copy("$path", "$dest_dir/{$dest_basename}");
}

$zip->close();
?>

A strange thing happend as this code worked only for 15 min now throwing warnings

( ! ) Warning: copy(myzipx/x/x.pdf): failed to open stream: No such file or directory in C:\wamp64\www\zip_ex\x\zip_img.php on line 21

But the file exists and echoing the correct file name. Don't understand what seems to be the problem .. Any help is appreciated.


Solution

  • Your try with copy() was the right thing. Unlike ZipArchive::extractTo() (which extract and create also the sub folders in the destination), the method copy() just copy/extract the specified file from the archive to the destination.

    This example should work:

    $archive = "testarchive.zip";
    $dest_dir = "./dest";
    if (!is_dir($dest_dir)) {
        if (!mkdir($dest_dir, 0755, true)) die("failed to make directory $dest_dir\n");
    }
    $zip = new ZipArchive;
    if (!$zip->open($archive)) die("failed to open $archive");
    
    for($i = 0; $i < $zip->numFiles; $i++) {
        $file_name = $zip->getNameIndex($i);
        $file_info = pathinfo($file_name);
        $file_ext = pathinfo($file_name, PATHINFO_EXTENSION);
        if (preg_match('/pdf/i', $file_ext)) {
            copy("zip://".$archive."#".$file_name, $dest_dir.'/'.$file_info['basename']);
        }
    }                  
    $zip->close();
    

    Testarchiv structure:

    xxxxx@xxxxxx:~/Documents$ tree testarchive
    testarchive
    └── test
        └── blubb
            └── test.pdf
    

    The folder testarchive is then compressed to testarchive.zip.

    After running code above:

    xxxxx@xxxxxx:~/Documents$ tree dest
    dest
    └── test.pdf