Watchful Protector
Watchful Protector

Reputation: 396

Zipping up a folder without extra folders in the zipped file

So, I understand it's pretty easy to zip a folder and its contents given that php.net and stackoverflow are full of sample codes. I am trying to zip up a folder as well. This is my code:

$zip = new ZipArchive;
$zip->open('myzip.zip', ZipArchive::CREATE);
foreach (glob("/Volumes/Data/Users/username/Desktop/Archive/some/thisFolder/*") as $file) {
    $zip->addFile($file);
}
$zip->close();

My script is running in a folder, say on Desktop, and I want to zip thisFolder and its contents. The above code WORKS. But, the problem is that when I unzip the myzip.zip created, I get a structure like

Volumes>Data>Users>username>Desktop>Archive>some>thisFolder

and then I find the contents inside the 8th folder (thisFolder) in this case. How can I change this code so that when I unzip myzip.zip,I would straightaway see the folder thisFolder with the contents inside it instead of having to navigate through folders 7 times before getting my content?

I tried to change the path and silly things like that. But, it doesn't work.

Thanks

Upvotes: 0

Views: 1656

Answers (2)

MatRt
MatRt

Reputation: 3534

bool ZipArchive::addFile ( string $filename [, string $localname ] )

filename The path to the file to add.

localname local name inside ZIP archive.

You can use the pathinfo function to each $file in your loop, in order to retrieve the filename without the path, and then, use it as second parameter to the addFile method.

pathinfo doc here

Here is an example that could solve your problem:

// Create your zip archive
$zip = new ZipArchive;

// open it in creation mode
$zip->open('myzip.zip', ZipArchive::CREATE);

// Loop on all your file
$mask = "/Volumes/Data/Users/username/Desktop/Archive/some/thisFolder";
$allAvailableFiles = glob($mask . "/*")
foreach ($allAvailableFiles as $file)
{
    // Retrieve pathinfo
    $info = pathinfo($file);

    // Generate the internal directory
    $internalDir = str_replace($mask, "", $info['dirname']);

    // Add the file with internal directory
    $zip->addFile($file, $internalDir . "/" . $info['basename']);
}

$zip->close();

Upvotes: 1

Barmar
Barmar

Reputation: 780724

If you want everything in the file to be a name relative to your starting folder, use chdir() to start from there:

chdir("/Volumes/Data/Users/username/Desktop/Archive/some/thisFolder");
foreach (glob("*") as $file) {
    $zip->addFile($file);
}

Actually, I don't think this will work when $file is a subdirectory -- addFile doesn't recurse automatically. There's a comment in the documentation that shows how to write a recursive zip function:

http://www.php.net/manual/en/ziparchive.addemptydir.php

Upvotes: 1

Related Questions