Anthony
Anthony

Reputation: 1876

zip files in PHP from another directory without a path structure

I'm trying to zip two files in another directory without zipping the folder hierarchy as well.

The event is triggered by a button press, which causes Javascript to send information using AJAX to PHP. PHP calls a Perl script (to take advantage of Perl's XLSX writer module and the fact that PHP kind of sucks, but I digress...), which puts the files a few folders down the hierarchy. The relevant code is shown below.

system("createFiles.pl -ids ${rows} -test ${test} -path ${path}",$retVal);

`zip ${path}/{$test}_both.zip ${path}/${test}.csv ${path}/${test}.xlsx`;
`zip ${path}/{$test}_csv.zip  ${path}/${test}.csv`;

The problem is the zip file has ${path} hierarchy that has to be navigated before the files are shown as seen below:

Zip with hierarchy

I tried doing this (cd before each zip command):

system("createFiles.pl -ids ${rows} -test ${test} -path ${path}",$retVal);

`cd ${path}; zip {$test}_both.zip ${test}.csv ${test}.xlsx`;
`cd ${path}; zip {$test}_csv.zip  ${test}.csv`;

And it worked, but it seems like a hack. Is there a better way?

Upvotes: 2

Views: 2369

Answers (2)

webaware
webaware

Reputation: 2841

The ZipArchive answer by Oldskool is good. I've used ZipArchive and it works. However, I recommend PclZip instead as it is more versatile (e.g. allows for zipping with no compression, ideal if you are zipping up images which are already compressed, much faster). PclZip supports the PCLZIP_OPT_REMOVE_ALL_PATH option to remove all file paths. e.g.

$zip = new PclZip("$path/{$test}_both.zip");
$files = array("$path/$test.csv", "$path/$test.xlsx");

// create the Zip archive, without paths or compression (images are already compressed)
$properties = $zip->create($files, PCLZIP_OPT_REMOVE_ALL_PATH);
if (!is_array($properties)) {
    die($zip->errorInfo(true));
}

Upvotes: 1

Oldskool
Oldskool

Reputation: 34837

If you use PHP 5 >= 5.2.0 you can use the ZipArchive class. You can then use the full path as source filename and just the filename as target name. Like this:

$zip = new ZipArchive;
if($zip->open("{$test}_both.zip", ZIPARCHIVE::OVERWRITE) === true) {
    // Add the files here with full path as source, short name as target
    $zip->addFile("${path}/${test}.csv", "${test}.csv");
    $zip->addFile("${path}/${test}.xlsx", "${test}.xlsx");
    $zip->close();
} else {
    die("Zip creation failed.");
}

// Same for the second archive
$zip2 = new ZipArchive;
if($zip2->open("{$test}_csv.zip", ZIPARCHIVE::OVERWRITE) === true) {
    // Add the file here with full path as source, short name as target
    $zip2->addFile("${path}/${test}.csv", "${test}.csv");
    $zip2->close();
} else {
    die("Zip creation failed.");
}

Upvotes: 1

Related Questions