Ne-Lexa / php-zip

PhpZip is a php-library for extended work with ZIP-archives.
MIT License
493 stars 60 forks source link

Cannot rename temp file to save on saveAsFile #54

Closed htcrkrishnamoorthy closed 4 years ago

htcrkrishnamoorthy commented 4 years ago

Just using below lines to add another file to existing ZIP

$destination = "C:/wamp64/www/oc3/test.zip";
$zipFile = new \PhpZip\ZipFile();
$zipFile->openFile($destination);
$retValue = $zipFile->addFile("backup.log");
$zipFile->saveAsFile($destination);
$retValue = $zipFile->close();

When it comes saveAsFile. it gives access denied error by rename() function on line 1614 of ZipFile.php where you are trying to rename temp file to ZIP. The folder has full access permission. May be because the $destination is still open in the memory and it is not able to move the file.

If I am creating a brand new zip file and use saveAsFile, it is working fine

Ne-Lexa commented 4 years ago

Hello. Test your code with a modified version

composer require nelexa/zip:dev-feature/overwrite
htcrkrishnamoorthy commented 4 years ago

Don't see any difference. Still see the same error

Ne-Lexa commented 4 years ago

What is the result of this code?

<?php

var_dump(is_writable('C:/wamp64/www/oc3/test.zip'));

Since this is Windows, use backslashes in the file name.

$destination = 'C:\wamp64\www\oc3\test.zip';
$zipFile = new \PhpZip\ZipFile();
$zipFile
    ->openFile($destination)
    ->addFile('backup.log')
    ->rewrite() // or ->saveAsFile($destination)
    ->close()
;
htcrkrishnamoorthy commented 4 years ago

var_dump(is_writable('C:/wamp64/www/oc3/test.zip')); was added before calling rename() in saveAsFile function in ZipFile.php

It returns true

C:\wamp64\storage\vendor\nelexa\zip\src\ZipFile.php:1613:boolean true

Changed code to use rewrite() instead of saveAsFile. Still the error is same

Removed @ before rename() function to get the exact error and is below Warning: rename(C:\wamp64\www\oc3\test.zip.temp5eb0d6d4945a18.96620773,C:\wamp64\www\oc3\test.zip): Access is denied. (code: 5) in C:\wamp64\storage\vendor\nelexa\zip\src\ZipFile.php on line 1614

Ne-Lexa commented 4 years ago

This seems like a server setup problem, not a library problem. Try to execute this code in php-cli mode.

What does the file C:\wamp64\www\oc3\test.zip contain? Are you sure you want to update it, and not save the file to another path?

ckwsoft commented 4 years ago

Hi guys, I haved the same problem and this moment I fixed it like this: ` public function saveAsFile($filename) { $filename = (string) $filename;

    $tempFilename = $filename . '.temp' . uniqid('', true);

    if (!($handle = @fopen($tempFilename, 'w+b'))) {
        throw new InvalidArgumentException('File ' . $tempFilename . ' can not open from write.');
    }
    $this->saveAsStream($handle);

    sleep(2);

    if (!@rename($tempFilename, $filename)) {
        if (is_file($tempFilename)) {
            unlink($tempFilename);
        }

        throw new ZipException('Can not move ' . $tempFilename . ' to ' . $filename);
    }

    return $this;
}`

I dont know if is a good solution but that fix the problm. tell me il there is another solution.

htcrkrishnamoorthy commented 4 years ago

Thank you @ckwsoft . I don't think this is a environment related issue. This was happening on other servers as well. The saveAsStream seems to have the file handle still open even if it is exclusively closing it. I will try your solution.

Ne-Lexa commented 4 years ago

@htcrkrishnamoorthy, @ckwsoft, version 3.3.3 was released. Check if the issue is resolved.