【问题标题】:ZipArchive PHP adding only files without directories from the whole pathZipArchive PHP 仅添加整个路径中没有目录的文件
【发布时间】:2013-08-26 05:29:12
【问题描述】:

各位程序员:

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

  1. Here

  2. And here

所以问题是:解压下载的'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->files 这不是我想要实现的:)

PHP 5.4.4

Windows XP、XAMPP

编辑

尝试使用http://www.phpconcept.net/pclzip/ 库并遇到同样的问题。 同样在我的家用 PC (win7) 上,此代码运行良好。

这就引出了一个问题:有什么我不知道的设置我应该满足的吗?

【问题讨论】:

    标签: php ziparchive


    【解决方案1】:

    我完全不知道为什么会这样:)

    我真的相信,我的电脑进入了 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,考虑到他在这里获得的分数,我也在考虑他的方法..

    【讨论】:

    • 只是好奇 getcwd() 的值是什么。看起来您正在将相对路径转换为绝对路径。
    • 这是来自 $zip->addFile 的 php 手册的第一条评论。注意:在不存在的文件上调用 $zip->addFile() 将成功并返回 TRUE,将失败延迟到您进行最后的 $zip->close() 调用,这将返回 FALSE 并可能让您抓狂你的头。如果您将多个文件添加到一个 zip 并且您的 $zip->close() 调用返回 FALSE,请确保您添加的所有文件确实存在。在调用 $zip->addFile() 之前,使用 file_exists() 或 is_readable() 检查每个文件也是一个好主意。
    • getcwd() 返回“C:\xampp\htdocs\test_tool\app\webroot”。还阅读了该评论,并认为由于正在创建 zip 存档,因此它可以工作(应该已经将 $zip->close() 打印出来,下次遇到问题时会知道)。
    【解决方案2】:

    在 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 标志一起使用。

    【讨论】:

    • 嗨,我试过你的代码是这样的:$phar = new PharData( 'tmp_zips/file.zip' ); $phar->buildFromDirectory( '/uploadify/files/test1', '~[.][0-9a-z]+$~i' );我收到了这个错误:RecursiveDirectoryIterator::__construct(/uploadify/files/test1,/uploadify/files/test1): The system cannot find the path specified. (code: 3)
    • @IgorLacik:似乎表明您输入了错误的路径。
    【解决方案3】:

    我已经运行了您的代码,它按预期工作。因此,据我所知,有 3 件事可能会出错。

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

    【讨论】:

    • 如果你有时间,请看看我的回答,让我知道它为什么有效:)
    【解决方案4】:

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

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

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

    【讨论】:

    • 如果你有时间,请看看我的回答,让我知道它为什么有效:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 2022-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-29
    • 2014-06-06
    相关资源
    最近更新 更多