ZipArchive PHP只添加整个路径中没有目录的文件

时间:2013-08-23 08:23:14

标签: php ziparchive

研究员:

讨厌问这个问题,我相信正确地回答了两次:

  1. Here

  2. And here

  3. 所以问题是:当解压缩下载的'file.zip'时,解压后,它包含路径中的所有文件夹,即使很难,我在addFile函数中指定了本地文件。我希望zip文件不包含任何子文件夹,只包含文件。

    $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);
    

    有人能看到这段代码有什么问题吗?

    其他信息:

    我,ofc,使用相对于webroot的路径,但在提取的文件夹中的文件夹层次结构之后: 提取到文件 - > 'my_file.zip' 是 C-> xampp-> htdocs-> my_cakephp_web_app-> app-> webroot->文件这不是我想要实现的目标:)

    PHP 5.4.4

    Windows XP,XAMPP

    修改

    尝试使用http://www.phpconcept.net/pclzip/库并遇到同样的问题。 同样在我的家用电脑(win7)上,这段代码效果很好。

    这提出了一个问题:我有什么设置我不应该知道吗?

4 个答案:

答案 0 :(得分:4)

我已运行您的代码,它按预期工作。因此,我可以看到有三件事可能出错。

尝试使用这些标志,以防旧文件仍然存在并且没有被覆盖(不清楚$ obj ['Name']设置为什么) 如果您阅读php手册中的注释,使用ZIPARCHIVE :: CREATE vs ZIPARCHIVE :: OVERWRITE会有不同程度的成功,所以使用两者都可以。

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

Pathinfo可能失败并返回整个路径或由于某种原因返回null

是否可以在pathinfo输出上执行var_dump,只是为了确认它是你期望的那样?

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 ) );
}

也许你的os / php版本有一个带有addFile功能的错误(不太可能,因为我看不到任何其他解释,所以抓住稻草)

答案 1 :(得分:3)

在PHP 5.3中,应该这样做:

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

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

您还可以将PharData::buildFromIteratorLEAVES_ONLY标记一起使用。

答案 2 :(得分:2)

您需要测试每个文件以查看它是否是文件(而不是目录,符号链接等):

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

这是使用filetype,但您也可以使用is_file

答案 3 :(得分:1)

我完全不知道为什么这样做有效:)

我真的相信,我的电脑进入了天网模式,并以某种方式使用addFile方法:)

任何能够合理解释所发生事情的人都将获得+50奖金:)

    $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 );

修改

此外,在临时文件没有删除自己的问题之后,我切换到了http://www.phpconcept.net/pclzip/,这很有效。

另外,Alix Axel在下面提到了PharData,考虑到他在这里获得的分数,我也在考虑他的方法......