【问题标题】:Using ziparchive or other php script to allow user to download all files from a folder in zip使用 ziparchive 或其他 php 脚本允许用户从 zip 文件夹中下载所有文件
【发布时间】:2015-11-05 22:19:04
【问题描述】:

所以我想为我的用户提供从我的站点的特定文件夹/目录下载所有文件的选项(我们称之为批量下载)。

id 喜欢做的是当用户单击链接/按钮时,脚本将创建一个包含特定文件夹中所有文件的临时 zip 文件,并且用户将能够下载它。 (如果有意义,我将需要不同页面上的链接/按钮的不同实例来从我选择的其他文件夹下载文件)。 zip 文件将在一段时间后被删除。下载完成后说什么。我认为 ziparchive 可以做到这一点,但我不知道从哪里开始或如何实现它。它是一个 joomla 网站,我找不到任何可以做到这一点的扩展。

我不知道关于 php 的第一件事,所以如果可能的话,我希望有人愿意帮助我完成这项工作。谢谢

【问题讨论】:

    标签: php download ziparchive


    【解决方案1】:

    如果您的服务器允许从 PHP 执行 shell 命令,并且安装了 zip,您可以使用 passthru( "zip - directory" ) 即时生成 zip。 - 表示要写入 stdout,这样您就不必处理临时文件清理。

    下面是这样一个脚本的概要:

    <?php
    if ( ! $dir = get_my_directory() )
        die("Illegal call.");
    
    header( 'Content-Type: application/zip' );
    header( 'Content-Disposition: attachment; filename=\"your.zip\"' );
    passthru( 'zip -r - ' . escapeshellarg( $dir ) );
    
    /**
     * @return false/null or the directory to zip.
     */
    function get_my_directory() {
        ....
        return ....;
    }
    

    无论您如何实现get_my_directory(),请确保任何人都无法在您的服务器上指定任何路径!

    另外,不要生成任何输出(没有 echo/print 或警告),因为这样要么不会设置标头,要么会损坏 zip 二进制数据。

    除此之外,PHP 的ZipArchive 页面上还有代码示例和文档。

    更新

    (@ OP:如果你不懂 PHP,我不太确定你在做什么来实现 PHP 解决方案。但是,假设你想学习。)

    假设您有 3 个公共目录可供下载,并且任何人都可以下载它们。您将实现如下:

    function get_my_directory() {
        // list of the directories you want anyone to be able to download.
        // These are key-value pairs, so we can use the key in our URLs
        // without revealing the real directories.
        $my_directories = array(
           'dir1' => 'path/to/dir1/',
           'dir2' => 'path/to/dir2/',
           'dir3' => 'path/to/dir3/'
        );
    
        // check if the 'directory' HTTP GET parameter is given:
        if ( ! isset( $_GET['directory'] ) )
            return null;               // it's not set: return nothing
        else
            $dir = $_GET['directory']; // it's set: save it so we don't have
                                       // to type $_GET['directory'] all the time.
    
        // validate the directory: only pre-approved directories can be downloaded
        if ( ! in_array( $dir, array_keys( $my_directories ) ) )
           return null;                    // we don't know about this directory
        else
           return $my_directories[ $dir ]; // the directory: is 'safe'.
    }
    

    是的,您将第一个和第二个代码示例粘贴到一个 .php 文件中(确保将第一个 get_my_directory 函数替换为第二个),位于服务器上可访问的某个位置。

    如果您调用文件“download-archive.php”,并将其放在 DocumentRoot 中, 您可以以http://your-site/download-archive.php?directory=dir1 等身份访问它。

    以下是一些参考资料:

    更新 2

    这是使用 ZipArchive 的完整脚本。它只在目录中添加文件;没有子目录。

    <?php
    if ( ! $dir = get_my_directory() )
        die("Illegal call.");
    
    $zipfile = make_zip( $dir );
    register_shutdown_function( function() use ($zipfile) {
        unlink( $zipfile ); // delete the temporary zip file
    } );
    
    header( "Content-Type: application/zip" );
    header( "Content-Disposition: attachment; filename=\"$zipfile\"" );
    readfile( $zipfile );
    
    function make_zip( $dir )
    {
        $zip = new ZipArchive();
        $zipname = 'tmp_'.basename( $dir ).'.zip';  // construct filename
        if ($zip->open($zipname, ZIPARCHIVE::CREATE) !== true)
            die("Could not create archive");
    
    
        // open directory and add files in the directory
        if ( !( $handle = opendir( $dir ) ) )
            die("Could not open directory");
    
        $dir = rtrim( $dir, '/' );      // strip trailing /
        while ($filename = readdir($handle)) 
            if ( is_file( $f = "$dir/$filename" ) )
                if ( ! $zip->addFile( $f, $filename ) )
                    die("Error adding file $f to zip as $filename");
    
        closedir($handle);
    
        $zip->close();
    
        return $zipname;
    }
    
    
    /**
     * @return false/null or the directory to zip.
     */
    function get_my_directory() {
        // list of the directories you want anyone to be able to download.
        // These are key-value pairs, so we can use the key in our URLs
        // without revealing the real directories.
        $my_directories = array(
           'dir1' => 'path/to/dir1/',
           'dir2' => 'path/to/dir2/',
           'dir3' => 'path/to/dir3/'
        );
    
        // check if the 'directory' HTTP GET parameter is given:
        if ( ! isset( $_GET['directory'] ) )
            return null;               // it's not set: return nothing
        else
            $dir = $_GET['directory']; // it's set: save it so we don't have
                                       // to type $_GET['directory'] all the time.
    
        // validate the directory: only pre-approved directories can be downloaded
        if ( ! in_array( $dir, array_keys( $my_directories ) ) )
           return null;                    // we don't know about this directory
        else
           return $my_directories[ $dir ]; // the directory: is 'safe'.
    }
    

    【讨论】:

    • 老实说,我不知道关于 php 的第一件事,所以你所说的对我来说就像是一种不同的语言,并不意味着不尊重或任何事情。所以你粘贴的代码我只是将它添加为一个 php 文件。链接/按钮也将在我在 joomla 中创建的文章中,所以我如何将这些链接放在指向该 php 文件的文章中。
    • 好的,所以我试了一下,它去了 mysite/batchdownload.php?directory=dir1。我得到的只是一个用“your.zip”下载的 0 字节文件。我应该补充一点,我不希望任何人下载文件,也许它们可以被加密或其他东西。这是我添加的代码。很抱歉无法发布它,因为它在评论框中说太多字符。 drive.google.com/open?id=0B1pK8Pv1aiBuVjNwR3ZwRjdzQkE
    • 对不起,我打不开那个。它可能失败的几个原因:您在脚本中指定的目录 'dir1' =&gt; '....', 不存在,或者您的服务器不允许从 PHP 执行 shell 命令(如果此脚本不产生任何输出,则就是这样:&lt;?php exec("whoami");)。至于不允许任何人下载文件,这可能需要 Joomla 集成。我不能为你做这一切。好吧,我可以,但这不是 SO 的意义所在。
    • 嘿肯尼。谢谢回复。我正在使用不同的主机。 (使用 Godaddy)共享主机 atm 所以不确定它们是否允许执行 shell 命令。你知道他们有吗?我有一个解决方案,不允许每个人都使用扩展程序下载。现在只需要让脚本工作。我可以尝试使用另一个链接向您发送 php 文件吗?感谢您的帮助。
    • 这是一个 mediafire 林希望我没有违反任何规则。 mediafire.com/view/2x6b2nfx31kjuae/batchdownload.php
    猜你喜欢
    • 2017-02-10
    • 2016-02-22
    • 2016-06-14
    • 2023-04-07
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-15
    相关资源
    最近更新 更多