在您的代码中使用以下方法。这样您就不需要将用户重定向到 zip 文件的真实 url。您可以从任何 php 脚本提供 zip,例如,您的付款确认页面可以重定向到带有随机令牌的脚本,该令牌在首次下载/时间后过期-
//call this method for sending download file.
function sendDL($filename)
{
header("Content-length:".filesize($filename));
header('Content-Type: application/x-gzip'); // ZIP file
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="download.gz"');
header('Content-Transfer-Encoding: binary');
ob_end_clean(); //output buffer cleanup
_readfileChunked($filename);
}
function _readfileChunked($filename, $retbytes=true) {
$chunksize = 1*(1024*1024); // how many bytes per chunk
$buffer = '';
$cnt =0;
// $handle = fopen($filename, 'rb');
$handle = fopen($filename, 'rb');
if ($handle === false) {
return false;
}
while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes && $status) {
return $cnt; // return num. bytes delivered like readfile() does.
}
return $status;
}
将这些视为实用方法。从不推出任何其他脚本(即 no echo
)的任何脚本中,第一种方法可用于向用户发送文件。像这样称呼
<?php
$dlToken = $_GET['dltoken'];
$filename = '/path/to/secret.file';
//Check if this dlToken is in database/memcache or not. and if yes its expired or not.
if($yes)
{
sendDL($filename);
}
else
{
sendNack();
}
function sendNack()
{
echo '___DATA_NOT_FOUND___'; //NOTICE this is the only echo in this script. and it means we are not sending the file after all.
//header("HTTP/1.0 404 Not Found");
exit();
}
//put the two methods there
function sendDL($filename)
{
//...
}
function _readfileChunked($filename, $retbytes=true)
{
//...
}
?>
在您提供下载链接的页面/脚本上。生成一个随机的唯一令牌。您可以使用uniqid或mt_rand或两者兼而有之。将此与时间戳值一起保存在数据库中(您可以在上面提到的下载脚本中使用它来检查令牌是否已过期)。使用该令牌创建一个下载 url,如下所示
download.php?file=test.zip&token=the_unique_token×tamp=unix_timestamp