Jason
Jason

Reputation: 2727

Avoid absolute path names for zip file contents

I am writing in php. I have the following code:

$folder_to_zip = "/var/www/html/zip/folder";
$zip_file_location = "/var/www/html/zip/archive.zip";
$exec = "zip -r $zip_file_location  '$folder_to_zip'";

exec($exec);

I would like to have the zip file stored at /var/www/html/zip/archive.zip which it does but when I open that zip file the whole server path is inside the zip file. How do I write this so that the server path is NOT inside the zip file?

The script running this command is not in the same directory. It is located at /var/www/html/zipfolder.php

Upvotes: 3

Views: 3266

Answers (2)

Vasily Bezruchkin
Vasily Bezruchkin

Reputation: 360

Please check this PHP function that works fine on both Windows & Linux servers.

function Zip($source, $destination, $include_dir = false)
{
    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    if (file_exists($destination)) {
        unlink ($destination);
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }

    $source = realpath($source);

    if (is_dir($source) === true)
    {

        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

        if ($include_dir) {

            $arr = explode(DIRECTORY_SEPARATOR, $source);
            $maindir = $arr[count($arr)- 1];

            $source = "";
            for ($i=0; $i < count($arr) - 1; $i++) {
                $source .= DIRECTORY_SEPARATOR . $arr[$i];
            }

            $source = substr($source, 1);

            $zip->addEmptyDir($maindir);

        }

        foreach ($files as $file)
        {
            // Ignore "." and ".." folders
            if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
                continue;

            $file = realpath($file);

            if (is_dir($file) === true)
            {
                $zip->addEmptyDir(str_replace($source . DIRECTORY_SEPARATOR, '', $file . DIRECTORY_SEPARATOR));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . DIRECTORY_SEPARATOR, '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

Upvotes: 1

Chris Stratton
Chris Stratton

Reputation: 40357

zip tends to store files with whatever path it was given to access them. Greg's comment gives you a potential fix for that specific to your current directory tree. More generally, you could - a bit crudely - do something like this

$exec = "cd '$folder_to_zip' ; zip -r '$zip_file_location  *'"

Often though you want the last directory to be part of the stored name (it's kind of polite, so whoever unzips doesn't dump all the files into their home directory or whatever), you could accomplish that by splitting it out into a separate variable with a text processing tool and then doing something like

$exec = "cd '$parent_of_folder' ; zip -r '$zip_file_location $desired_folder'"

Warning: didn't have time to test any of this for silly mistakes

Upvotes: 5

Related Questions