文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

PHP中的下载文件

2023-05-24 08:29

关注

在开发网站或者应用程序时,我们经常需要实现文件下载功能,通过PHP可以方便地实现该功能。本文将介绍如何使用PHP来实现文件下载功能。

一、文件下载流程

在下载文件前,我们需要了解一下下载的流程:

  1. 用户在网页或者应用程序上点击下载按钮;
  2. 服务器接受下载请求;
  3. 服务器检查用户权限和文件存在性;
  4. 服务器将文件发送给用户;
  5. 用户接收文件并保存。

二、准备下载文件

在PHP中,我们可以使用readfile函数来读取文件内容并输出到浏览器。但是,我们需要确保文件存在,否则将会抛出异常。下面是一个简单的代码示例:

$file_path = '/path/to/your/file/yourfile.extension';
if (file_exists($file_path))
{
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename=' . basename($file_path));
    header('Content-Transfer-Encoding: binary');
    header('Content-Length: ' . filesize($file_path));
    readfile($file_path);
    exit;
}
else
{
    die('File not found.');
}

以上代码中,我们首先使用file_exists函数检查文件是否存在,如果文件存在,则设置HTTP头文件来告诉浏览器将要下载一个文件,并在Content-Disposition中指定文件名,Content-Type指定文件类型,并使用readfile函数来输出文件内容。

三、防止文件下载被盗链

由于浏览器的本质,可能会导致某些不良站点盗用您的文件,因此我们需要防止文件下载被盗链。

我们可以添加以下代码来防止文件下载被盗链:

$referer = $_SERVER['HTTP_REFERER'];
if ($referer && !preg_match('/^https?://' . $_SERVER['SERVER_NAME'] . '/', $referer))
{
    header("HTTP/1.1 403 Forbidden");
    die("Access denied.");
}

该代码将检查HTTP_REFERER头信息并确保其与当前服务器的域名匹配,如果不匹配,则返回403状态码,禁止访问。

四、实现分段下载

在下载较大的文件时,可能需要实现分段下载功能,以加快下载速度并减少网络带宽的占用。借助于HTTP 1.1的Range头信息,我们可以轻松地实现分段下载。

以下是一个示例代码:

$file_path = '/path/to/your/file/yourfile.extension';
if (file_exists($file_path))
{
    $size = filesize($file_path);
    $start = 0;
    $end = $size - 1;
    
    if (isset($_SERVER['HTTP_RANGE']))
    {
        if (preg_match('/bytes=h*(d+)-(d*)[D.*]?/i', $_SERVER['HTTP_RANGE'], $matches))
        {
            $start = intval($matches[1]);
            if (!empty($matches[2]))
            {
                $end = intval($matches[2]);
            }
        }
    }
    if ($start > $end || $end > $size - 1 || $start < 0)
    {
        header('HTTP/1.1 416 Requested Range Not Satisfiable');
        header("Content-Range: bytes $start-$end/$size");
        exit;
    }
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename=' . basename($file_path));
    header('Content-Transfer-Encoding: binary');
    header("Content-Range: bytes $start-$end/$size");
    header('Accept-Ranges: bytes');
    header('Content-Length: ' . ($end - $start + 1));
    header("Cache-control: private");
    header('Pragma: private');
    header('Expires: ' . gmdate('D, d M Y H:i:s T', time() + 3600));
    
    $fp = fopen($file_path, 'rb');
    fseek($fp, $start);
    $buffer_size = 1024 * 8; //每次读取8 KB
    $bytes_send = 0;
    while (!feof($fp) && ($bytes_send < $end - $start + 1))
    {
        $buffer = fread($fp, $buffer_size);
        echo $buffer;
        flush();
        $bytes_send += strlen($buffer);
    }
    fclose($fp);
    exit;
}
else
{
    die('File not found.');
}

以上代码中,我们首先检查HTTP_RANGE头信息,如果该头信息不存在,则输出整个文件。如果该头信息存在,则解析出起始偏移量和结束偏移量,然后使用fseek函数定位文件指针,使用fread函数读取文件内容并输出到浏览器。

五、结论

在PHP中实现文件下载功能不难,我们只需要检查文件是否存在并设置正确的HTTP头信息即可。使用HTTP 1.1 Range头信息可以轻松地实现分段下载,防止文件下载被盗链可以保护文件的安全。因此,我们可以根据需求来选择实现所需的功能,以达到更好的用户体验。

以上就是PHP中的下载文件的详细内容,更多请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯