简体   繁体   中英

ZipArchive PHP adding only files without directories from the whole path

Fellow coders:

Hate to ask this question, as it was, I belive correctly answered two times:

  1. Here

  2. And here

So the problem is: when unzipping the downloaded 'file.zip', after unzipping, it contains all the folders from the path, even tough I specified the local file in the addFile function. I'd like the zip file not to contain any subfolder, just files.

$zipname = str_replace(' ', '_', $obj['Name']) . '.zip';

$zip = new ZipArchive();

$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
    // $file looks like this: webroot/uploadify/files/file.jpg
    $zip->addFile($file, pathinfo($file, PATHINFO_BASENAME));
}

$zip->close();

header('Content-Description: File Transfer');
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=" . $zipname);
header("Pragma: no-cache");
header("Expires: 0");
header('Content-Length: ' . filesize($zipname));

readfile($zipname);

Can anyone see what's the problem with this code?

Additional info:

I, ofc, use paths relative to the webroot, but the folder hierarchy in the extracted folder after: extract to file -> 'my_file.zip' is C->xampp->htdocs->my_cakephp_web_app->app->webroot->files which is not exactly what I wanted to achieve :)

PHP 5.4.4

Windows XP, XAMPP

EDIT

Tried using the http://www.phpconcept.net/pclzip/ library and had the same problem. Also on my home PC ( win7 ) this code worked well.

This brings up a question: Are there any settings I should meet that I'm not aware of?

I have run your code and it works as expected. So there are 3 things that could be going wrong from what I can see.

Try using these flags in case an old file still exists and it is not being overwritten (it is not clear what $obj['Name'] is set to ) If you read the comments in the php manual, there are varying degrees of success using ZIPARCHIVE::CREATE vs ZIPARCHIVE::OVERWRITE, so perhaps using both will work.

$zip->open( $zipname, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE );

Pathinfo could be failing and returning the whole path or null for some reason

Is it possible to do a var_dump on the pathinfo output, just to confirm it is what you expect it to be?

foreach ( $files as $file )
{
     var_dump(pathinfo( $file, PATHINFO_BASENAME ));

    // $file looks like this: webroot/uploadify/files/file.jpg
    // $zip->addFile( $file, pathinfo( $file, PATHINFO_BASENAME ) );
}

Maybe there is a bug with your os/php version with addFile function (unlikely, grasping at straws here as i can't see any other explanation)

In PHP 5.3 this should do it:

$phar = new PharData('file.zip');

// add all files in the folder, only include files with extensions
$phar->buildFromDirectory('/directory', '~[.][0-9a-z]+$~i');

You could also use PharData::buildFromIterator with the LEAVES_ONLY flag.

You need to test each file to see if it's a file (rather than a directory, symlink, etc):

foreach ( $files as $file )
{
    if(filetype($file) == 'file') {
        $zip->addFile( $file, pathinfo( $file, PATHINFO_BASENAME ) );
    }
}

This is using filetype , but you could also use is_file .

I have absolutely no idea why this is working :)

I'd actually believe, that my PC entered a Skynet mode and got the addFile method to work somehow :)

Anyone who can plausibly explain what happened will get the +50 bonus :)

    $zipname = str_replace( ' ', '_', $obj['Name'] ) . '.zip';

    $zip = new ZipArchive;

    $zip->open( $zipname, ZipArchive::CREATE );

    foreach ( $files as $file )
    {
        // the str_replace made it work???
        $zip->addFile( str_replace( '/webroot', '', getcwd() . '/' . $file ), pathinfo( $file, PATHINFO_BASENAME ) );
    }

    $zip->close();

    header("Content-type: application/zip");
    header("Content-Disposition: attachment; filename=" . $zipname);
    header('Content-Length: ' . filesize( $zipname ));

    readfile( $zipname );

EDIT:

Also, after having some more trouble with temporary files not deleteing themselves, I switched to http://www.phpconcept.net/pclzip/ , which works well.

Also, Alix Axel mentioned PharData below, given the amount of score he's earned here, I'm considering his approach as well..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM