7

各位程序员:

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

  1. 这里

  2. 和这里

所以问题是:解压缩下载的“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/库并遇到同样的问题。同样在我的家用 PC ( win7 ) 上,此代码运行良好。

这就提出了一个问题:是否有任何我不知道的设置我应该满足?

4

4 回答 4

4

我已经运行了您的代码,它按预期工作。因此,从我所看到的情况来看,有 3 件事可能会出错。

尝试使用这些标志以防旧文件仍然存在并且没有被覆盖(不清楚 $obj['Name'] 设置为什么)如果您阅读了 php 手册中的注释,则成功程度不同使用 ZIPARCHIVE::CREATE 与 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 函数的错误(不太可能,在这里抓住稻草,因为我看不到任何其他解释)

于 2013-08-26T10:07:03.530 回答
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标志一起使用。

于 2013-08-31T09:11:44.593 回答
2

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

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

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

于 2013-08-23T08:27:07.877 回答
1

我完全不知道为什么这是有效的:)

我实际上相信,我的 PC 进入了 Skynet 模式并让 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,鉴于他在这里获得的分数,我也在考虑他的方法。

于 2013-08-26T11:25:32.260 回答