做网站的时候,有时候想要提供一些资源给用户下载,但是往往别的网站直接复制本站的下载链接提供给他的用户下载,而消耗自己服务器的资源。如何完美解决这个方法呢?那就是一次性下载链接,每次下载链接都不一样,别人复制了你的下载链接也没有用。如何实现这个功能呢?


方法一:使用session


假定123.zip是我们想要提供给用户下载的文件资源,我们首先在文件介绍页面生成一个随机下载链接,比如我们的下载地址:https://www.wensha.info/  xiazai.php?code=(php随机生成的一个字符串,该变量命名为$code);然后我们把随机字符、时间和文件名称都存入session中。


第一步:在资源介绍页面把文件资源信息存入session


//设置时间和文件资源信息
session_start();
$_SESSION["$code"] = '123.zip';
$_SESSION["$code".'time'] = time();


当用户点击https://www.wensha.info/  xiazai.php?code=$code这个链接的时候,只通过get方式传递了一个变量,那就是code。接下来我们就需要通过获取code这个变量来解读文件资源的信息了。


第二步:通过GET值读取上一步存入的数据并把文件内容提供给下载者


<?php
$code = $_GET['code'];
session_start;
$file = $_SESSION["$code"];
$time = $_SESSION["$code".'time'];
if(time() - $time >= 5 * 60){//如果生成链接的时间超过5分钟
echo '该链接已经失效';
exit;
}else{
// 检查文件是否存在
if (file_exists($file)) {
    // 设置响应头,告诉浏览器该文件为下载文件
    header("Content-type: application/octet-stream");
    header("Content-Disposition: attachment; filename=123.zip");
    // 将文件输出给浏览器
    readfile($file);
    exit;
} else {
    // 文件不存在的处理逻辑
    echo "文件不存在";
    exit;
}
}
//清除SESSION数据,如果你网站登录使用的是SESSION,这里不建议你直接销毁SESSION,而是用下面的方法把SESSION的相关数据清除。
$_SESSION["$code"] = '';
$_SESSION["$code".'time'] = '';
?>


方法二:使用临时文件


这个针对大文件效率比方法一要快。思路是使用php把123.zip复制到临时目录,然后提供给用户下载。最后定时清理临时文件即可。


第一步:复制源文件并重新命名


我们将文件123.zip复制到cache/data目录并使用随机名称重新命名:


$sourceFile = '123.zip'; // 源文件路径
$destinationDirectory = 'cache/data/'; // 目标文件夹路径
// 生成随机文件名
$randomName = generateRandomString(10); // 使用自定义的随机字符串生成函数
// 目标文件路径
$destinationFile = $destinationDirectory . $randomName . '.zip';
// 复制文件
if (copy($sourceFile, $destinationFile)) {
    echo "文件复制成功!";
} else {
    echo "文件复制失败!";
}
// 生成指定长度的随机字符串
function generateRandomString($length) {
    $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}

//下载链接

$fileurl = 'https://www.wensha.info/'.$destinationFile;


当用户点击$fileurl,则把临时文件提供给用户,但是这里需要注意,还需要写一个文件来定期清理临时目录里的临时文件。


第二步:清理临时文件


要读取cache/data目录下所有文件的时间,并删除所有时间小于1小时前的文件,可以使用以下代码:


$directory = 'cache/data/'; // 目录路径
// 获取目录中的所有文件
$files = scandir($directory);
// 遍历文件
foreach ($files as $file) {
    if ($file !== '.' && $file !== '..') {
        $filePath = $directory . $file;
        // 获取文件修改时间
        $fileTime = filemtime($filePath);
        // 判断文件修改时间是否小于1小时前
        if ($fileTime < (time() - 3600)) {
            // 删除文件
            unlink($filePath);
            echo "已删除文件:$file<br>";
        }
    }
}


以上代码中,我们首先通过scandir()函数获取指定目录下的所有文件。然后使用循环遍历文件列表,并排除`.`和`..`目录。在循环中,我们获取每个文件的修改时间通过filemtime()函数,并将其与当前时间相比较。如果文件的修改时间早于1小时前(时间戳小于`time() - 3600`),则使用unlink()函数删除该文件。

动态URL下载链接的方式千万种,这里只介绍了最容易掌握的两种方法。本文主要是为你提供实现思路和方法,文章中的代码未经过测试,可能存在语法错误,还需仔细检测。