所以我想为我的用户提供从我的网站下载特定文件夹/目录中的所有文件的选项(我们称之为批量下载)。
我想做的是,当用户单击链接/按钮时,脚本将为特定文件夹中的所有文件创建一个临时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'.
}