使用ziparchive或其他php脚本,允许用户从zip中的文件夹下载所有文件


Using ziparchive or other php script to allow user to download all files from a folder in zip

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

我想做的是,当用户单击链接/按钮时,脚本将为特定文件夹中的所有文件创建一个临时zip文件,用户将能够下载它。zip文件将在一段时间后删除。下载完成后说。我认为zipparchive可以做到这一点,但我不知道从哪里开始,也不知道如何实现它。这是一个joomla网站,我找不到任何可以做到的扩展。

我不知道php的第一件事,所以如果可能的话,我希望有人愿意帮助我实现这一点。感谢

如果您的服务器允许从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函数),在服务器上可以访问的地方。

如果您调用文件"downloadarchive.php",并将其放置在DocumentRoot中,您可以将其作为http://your-site/download-archive.php?directory=dir1等访问

以下是一些参考资料:

  • PHP教程
  • 一般功能
  • 函数标头
  • 功能直通
  • 功能模具
  • 数组中的函数
  • 函数array_values

更新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'.
}