Problem creating zip for the same directory multiple times while zipping the directory

Hello,
I’m trying to compress a directory into zip format using php and or exec.
I cannot notice it in small size files, but when compressing 1.5GB in zip format, I can see the compression process by frequently updating the page in the cPanel File Manager.
I tried many things but I couldn’t fix the problem.
Sometimes, multiple compression processes continue in a row, as I show in the picture below.
Sometimes, the first compression process ends and another compression process starts immediately and ends when the second compression process is completed.
I implemented a session into the function, if the session is empty, I applied compression and locking, but the problem still persists.
I called the function on the simple page as shown below, and it performs multiple consecutive zip operations for the same directory.

I create a zip with exec, the process shown in the picture, but the same problem occurs with php zip.
It is the compression process for the same directory.


NOTE: If the file name is fixed, when creating zips one after the other, the same names after the compression process is completed are overwritten with the zip file just created.

If the file name is specified as date('Y-m-d-H-i-s') on the function page, it creates multiple files one second apart.

My codes on the page where I call the function

<?php 

require_once __DIR__ . '/zipyap.php';

$zipyap_sonucu = zipDataUsingSystem('../directoryname', '../ZIPLER/directoryname-2024-05-23-17-39-00.zip', 'directoryname');

$zipyap_sonucu = zipDataUsingZipArchive('../directoryname', '../ZIPLER/directoryname-2024-05-23-17-39-00.zip', 'directoryname');

echo '<pre>' . print_r($zipyap_sonucu, true) . '</pre>';

?>

It creates multiple zips but the result is only one

Array
(
    [0] => Zip Arşivi Başarıyla Oluşturuldu
    [dosya_adi] => ../ZIPLER/directoryname-2024-05-23-17-39-00.zip
)

My zip creation function code in zipyap.php file

if (!function_exists('zipDataUsingZipArchive')) {
    function zipDataUsingZipArchive($source, $destination, $comment = '') {
        $zipsonuc = [];

        // Kaynak dizin veya dosyanın var olup olmadığını kontrol et
        if (!file_exists($source)) {
            $zipsonuc[] = "Kaynak dosya veya dizin mevcut değil: " . $source;
            return $zipsonuc;
        }

        // Hedef dizinin mevcut olup olmadığını kontrol et ve gerekirse oluştur
        $destinationDirRealPath = dirname($destination);
        if (!file_exists($destinationDirRealPath)) {
            if (!mkdir($destinationDirRealPath, 0755, true)) {
                $zipsonuc[] = "Hedef dizin oluşturulamadı: " . $destinationDirRealPath;
                return $zipsonuc;
            }
        }

        // Kilit dosyasının yolunu belirleyin
        $lockFile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . md5(realpath($source)) . '.lock';

        // Kilit dosyasını oluştur ve kilitle
        $fp = fopen($lockFile, 'c');
        if (!$fp) {
            $zipsonuc[] = "Kilit dosyası oluşturulamadı: " . $lockFile;
            return $zipsonuc;
        }

        // Kilit işlemi
        if (!flock($fp, LOCK_EX | LOCK_NB)) {
            fclose($fp);
            $zipsonuc[] = "Başka bir zip işlemi devam ediyor: " . $source;
            return $zipsonuc;
        }

        // Zip işlemi
        $zip = new ZipArchive();
        if ($zip->open($destination, ZipArchive::CREATE) !== TRUE) {
            $zipsonuc[] = "Zip arşivi açılamadı: " . $destination;
            // Kilidi serbest bırak ve kilit dosyasını kapat
            flock($fp, LOCK_UN);
            fclose($fp);
            return $zipsonuc;
        }

        $sourceRealPath = realpath($source);

        if (is_dir($sourceRealPath)) {
            // Kaynak bir dizinse, tüm dosyaları ve alt dizinleri ekleyin
            $sourceIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($sourceRealPath), RecursiveIteratorIterator::LEAVES_ONLY);

            foreach ($sourceIterator as $file) {
                if (!$file->isDir()) {
                    $filePath = $file->getRealPath();
                    $relativePath = substr($filePath, strlen($sourceRealPath) + 1);
                    $zip->addFile($filePath, $relativePath);
                }
            }
        } elseif (is_file($sourceRealPath)) {
            // Kaynak bir dosyaysa, sadece bu dosyayı ekleyin
            $zip->addFile($sourceRealPath, basename($sourceRealPath));
        }

        // Yorum ekleme işlemi
        if ($comment !== '') {
            $zip->setArchiveComment($comment);
        }

        $zip->close();

        // Orijinal dosya adındaki tek tırnakları kaldır
        $destinationClean = str_replace("'", "", $destination);

        $zipsonuc[] = "Zip Arşivi Başarıyla Oluşturuldu";
        $zipsonuc["dosya_adi"] = $destinationClean;

        // Kilidi serbest bırak ve kilit dosyasını kapat
        flock($fp, LOCK_UN);
        fclose($fp);
        unlink($lockFile); // Kilit dosyasını sil

        return $zipsonuc;
    }
}

######################################################################################################################################################

if (!function_exists('zipDataUsingSystem')) {
    function zipDataUsingSystem($source, $destination, $comment = '') {
        $zipsonuc = [];

        // Kaynak dizin veya dosyanın var olup olmadığını kontrol et
        if (!file_exists($source)) {
            $zipsonuc[] = "Kaynak dosya veya dizin mevcut değil: " . $source;
            return $zipsonuc;
        }

        // Dosya yollarını işlemek ve güvenli hale getirmek
        $sourceRealPath = realpath($source);
        $destinationSafe = escapeshellarg($destination); // Sadece komut için güvenli hale getir

        // Kilit dosyasının yolunu belirleyin
        $lockFile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . md5($sourceRealPath) . '.lock';

        // Kilit dosyasını oluştur ve kilitle
        $fp = fopen($lockFile, 'c');
        if (!$fp) {
            $zipsonuc[] = "Kilit dosyası oluşturulamadı: " . $lockFile;
            return $zipsonuc;
        }

        // Kilit işlemi
        if (!flock($fp, LOCK_EX | LOCK_NB)) {
            fclose($fp);
            $zipsonuc[] = "Başka bir zip işlemi devam ediyor: " . $source;
            return $zipsonuc;
        }

        // Hedef dizinin mevcut olup olmadığını kontrol et ve gerekirse oluştur
        $destinationDirRealPath = dirname($destination);
        if (!file_exists($destinationDirRealPath)) {
            if (!mkdir($destinationDirRealPath, 0755, true)) {
                $zipsonuc[] = "Hedef dizin oluşturulamadı: " . $destinationDirRealPath;
                // Kilidi serbest bırak ve kilit dosyasını kapat
                flock($fp, LOCK_UN);
                fclose($fp);
                return $zipsonuc;
            }
        }

        // zip komutunu oluştur, kaynak dizinin içine girip içeriklerini ekle
        $command = "cd " . escapeshellarg($sourceRealPath) . " && zip -r $destinationSafe .";
        $output = [];
        $return_var = 0;
        exec($command, $output, $return_var);

        // Sonuçları kontrol et
        if ($return_var === 0) {
            // Yorum ekleme işlemi
            if ($comment !== '') {
                $comment = escapeshellarg(iconv(mb_detect_encoding($comment, mb_detect_order(), true), "UTF-8", $comment));
                $commentCommand = "zip -z $destinationSafe <<< $comment";
                exec($commentCommand);
            }

            // Orijinal dosya adındaki tek tırnakları kaldır
            $destinationClean = str_replace("'", "", $destination);

            $zipsonuc[] = "Zip Arşivi Başarıyla Oluşturuldu";
            $zipsonuc["dosya_adi"] = $destinationClean;
        } else {
            $zipsonuc[] = "Zip Arşivi Bir Hatadan Dolayı Oluşturulamadı: " . implode("<br>", $output);
        }

        // Kilidi serbest bırak ve kilit dosyasını kapat
        flock($fp, LOCK_UN);
        fclose($fp);
        unlink($lockFile); // Kilit dosyasını sil

        return $zipsonuc;
    }
}

Thank you from now

What value does creating that give you?

From time to time, I create backups of web directories in zip format and back them up to Google Drive.
The code below creates two consecutive zips of the same directory.
When it starts creating for the first “yonetim” directory, the name “Zisdf58”(as) is seen, and when the compression is finished, it saves it with the specified file name “file_name-2024-05-29-16-35-15.zip”.
It immediately starts to create a zip with the name “Zigjh555”(as) for the “management” again, once the compression is finished, it overwrites the file with “file_name-2024-05-29-16-35-15.zip” and the process is completed.

The function code below is working.
You can try.
Note: the file needs to be a few GB in size so that you can see the process.
I observe the compression process by frequently refreshing the “ZIPS” directory in the cPanel->File Manager area.

    function zipDataUsingSystem($source, $destination, $comment = '') {
        $zipsonuc = [];

        // Check if source directory or file exists
        if (!file_exists($source)) {
            $zipsonuc[] = "Source file or directory does not exist: " . $source;
            return $zipsonuc;
        }

        // Processing and securing file paths
        $sourceRealPath = realpath($source);
        $destinationSafe = escapeshellarg($destination); // Make it safe for command only

        // Specify the path to the lock file
        $lockFile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . md5($sourceRealPath) . '.lock';

        // Write to the log file that the lock file was created
        file_put_contents('/home/user/error.log', date('Y-m-d H:i:s') . " - Lock file is being created: " . $lockFile . "\n", FILE_APPEND);

        // Create and lock lock file
        $fp = fopen($lockFile, 'c');
        if (!$fp) {
            $zipsonuc[] = "Lock file could not be created: " . $lockFile;
            return $zipsonuc;
        }

        // Lock operation
        if (!flock($fp, LOCK_EX | LOCK_NB)) {
            fclose($fp);
            $zipsonuc[] = "Another zip process in progress: " . $source;
            // Write to the log file that it could not be locked.
            file_put_contents('/home/user/error.log', date('Y-m-d H:i:s') . " - Another zip process in progress: " . $source . "\n", FILE_APPEND);
            return $zipsonuc;
        }

        // Check if the target directory exists and create it if necessary
        $destinationDirRealPath = dirname($destination);
        if (!file_exists(KOKYOLU.$destinationDirRealPath)) {
            if (!mkdir(KOKYOLU.$destinationDirRealPath, 0777, true)) {
                $zipsonuc[] = "Could not create target directory: " . $destinationDirRealPath;
                // Release the lock and close the lock file
                flock($fp, LOCK_UN);
                fclose($fp);
                // Write to the log file that the directory could not be created
                file_put_contents('/home/user/error.log', date('Y-m-d H:i:s') . " - Could not create target directory: " . $destinationDirRealPath . "\n", FILE_APPEND);
                return $zipsonuc;
            }
        }

        // Write in the log file that the zip command will be run
        file_put_contents('/home/user/error.log', date('Y-m-d H:i:s') . " - Running zip command: " . $destination . "\n", FILE_APPEND);

        // Create the zip command, go into the source directory and add its contents
        $command = "cd " . escapeshellarg($sourceRealPath) . " && zip -r $destinationSafe .";
        $output = [];
        $return_var = 0;
        exec($command, $output, $return_var);

        // Check the results
        if ($return_var === 0) {
            // Comment adding process
            if ($comment !== '') {
                $comment = escapeshellarg(iconv(mb_detect_encoding($comment, mb_detect_order(), true), "UTF-8", $comment));
                $commentCommand = "zip -z $destinationSafe <<< $comment";
                exec($commentCommand);
            }

            // Remove single quotes in original filename
            $destinationClean = str_replace("'", "", $destination);

            $zipsonuc[] = "Zip Archive Created Successfully";
            $zipsonuc["dosya_adi"] = $destinationClean;

            // Write to the log file that the zip process was completed successfully.
            file_put_contents('/home/user/error.log', date('Y-m-d H:i:s') . " - Zip Archive Created Successfully: " . $destinationClean . "\n", FILE_APPEND);

        } else {
            $zipsonuc[] = "Zip Archive Could Not Be Created Due to an Error: " . implode("<br>", $output);
            // Write the error message to the log file
            file_put_contents('/home/user/error.log', date('Y-m-d H:i:s') . " - Zip Archive Could Not Be Created Due to an Error: " . implode(", ", $output) . "\n", FILE_APPEND);
        }

        // Release the lock and close the lock file
        flock($fp, LOCK_UN);
        fclose($fp);
        unlink($lockFile); // Delete lock file

        // Write to the log file that the lock file has been deleted
        file_put_contents('/home/user/error.log', date('Y-m-d H:i:s') . " - Lock file deleted: " . $lockFile . "\n", FILE_APPEND);

        return $zipsonuc;
    }

$source = "/home/user/yonetim";
$destination = "/home/user/ZIPS/file_name-2024-05-29-16-35-05.zip";
$comment = "yonetim"; //This zip will be added to the comment field

function zipDataUsingSystem($source, $destination, $comment);

I prepared a video to better understand the problem.
I update it frequently to see the progress from cPanel > File Management

The problem is your filenames. Those random names are temporary names while the process is happening. Than it gets renamed to the final name which you have given…

Solution: Add microsecond accuracy, or keep a counter for that days backups (can exclude the time if this is preferred)

I removed the directory locking option because I saw that it was not relevant.

The following codes are in the “zipcreate.php” file.
I “include” the “task.php” file and run the function in the “while()” loop.
I use “PHP CLI” cron jobs to run the “task.php” file, and since it runs every minute, it sends requests to the functions. To fix this problem, I lock the “task.php” file at the beginning of the page and release the lock at the end of the page when the task is finished.
There was a problem for more than a minute, but this problem has been fixed.
There is no problem in compressing the directory with the PHP archive, but when I compress it with exec, it creates two continuation zips as in the video and overwrites the existing file.

if (!function_exists('zipDataUsingSystem')) {
    function zipDataUsingSystem($source, $destination, $comment = '') {
        $zipsonuc = [];

        // Kaynak dizin veya dosyanın var olup olmadığını kontrol et
        if (!file_exists($source)) {
            $zipsonuc[] = "HATA: Kaynak dosya veya dizin mevcut değil: " . $source;
            return $zipsonuc;
        }

        // Dosya yollarını işlemek ve güvenli hale getirmek
        $sourceRealPath = realpath($source);
        if ($sourceRealPath === false) {
            $zipsonuc[] = "HATA: Kaynak yolu bulunamadı: " . $source;
            return $zipsonuc;
        }
        $destinationSafe = escapeshellarg($destination); // Sadece komut için güvenli hale getir

        // Hedef dizinin mevcut olup olmadığını kontrol et ve gerekirse oluştur
        $destinationDirRealPath = dirname($destination);
        if (!file_exists($destinationDirRealPath)) {
            if (!mkdir($destinationDirRealPath, 0777, true)) {
                $zipsonuc[] = "HATA: Hedef dizin oluşturulamadı: " . $destinationDirRealPath;
                return $zipsonuc;
            } else {
                //$zipsonuc[] = "Hedef dizin oluşturuldu: " . $destinationDirRealPath;
            }
        } else {
            //$zipsonuc[] = "Hedef dizin zaten mevcut: " . $destinationDirRealPath;
        }

        // zip komutunu oluştur
        if (is_dir($sourceRealPath)) {
            // Kaynak bir dizinse, içine girip içeriklerini ekle
            $command = "cd " . escapeshellarg($sourceRealPath) . " && zip -r $destinationSafe .";
        } elseif (is_file($sourceRealPath)) {
            // Kaynak bir dosyaysa, dosyayı ekle
            $sourceSafe = escapeshellarg($sourceRealPath);
            $command = "zip $destinationSafe $sourceSafe";
        } else {
            $zipsonuc[] = "HATA: Kaynak ne dosya ne de dizin: " . $sourceRealPath;
            return $zipsonuc;
        }

        $output = [];
        $return_var = 0;
        exec($command, $output, $return_var);

        // Sonuçları kontrol et
        if ($return_var === 0) {
            $zipsonuc[] = "Zip arşivi başarıyla oluşturuldu";

            // Yorum ekleme işlemi
            if ($comment !== '') {
                $comment = escapeshellarg(iconv(mb_detect_encoding($comment, mb_detect_order(), true), "UTF-8", $comment));
                $commentCommand = "echo $comment | zip -z $destinationSafe";
                exec($commentCommand, $commentOutput, $commentReturnVar);

                if ($commentReturnVar === 0) {
                    //$zipsonuc[] = "Yorum başarıyla eklendi.";
                } else {
                    $zipsonuc[] = "HATA: Yorum eklenemedi.";
                }
            }

            // Orijinal dosya adındaki tek tırnakları kaldır
            $destinationClean = str_replace("'", "", $destination);
            $zipsonuc["dosya_adi"] = $destinationClean;
        } else {
            $zipsonuc[] = "HATA: Zip arşivi oluşturulamadı. Hata kodu: $return_var";
            $zipsonuc[] = "Çıktı: " . implode("\n", $output);
        }

        return $zipsonuc;
    }
}

I call the function from “while()” in “task.php” as follows.
What could be wrong with the file name?

while ($row = $task->fetch()) {

$file_prefix = "webyonetim";
$file_date = date('Y-m-d-H-i-s');
$source = "/home/user/folder/";
$destination = "/home/user/zips/" . $file_prefix . "-" . $file_date;
$comment = $file_prefix;

zipDataUsingSystem($source, $destination, $comment);

}
Sponsor our Newsletter | Privacy Policy | Terms of Service