当前位置:首页 > PHP

php怎么实现下载

2026-04-03 05:15:29PHP

实现文件下载的基本方法

使用PHP的header()函数设置HTTP头信息,结合readfile()函数输出文件内容。以下是一个简单示例:

$file_path = '/path/to/your/file.pdf';
$file_name = 'download.pdf';

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file_name).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);
exit;

处理大文件下载

对于大文件,使用分块读取避免内存问题:

php怎么实现下载

$chunk_size = 1024 * 1024; // 1MB chunks
$handle = fopen($file_path, 'rb');
while (!feof($handle)) {
    echo fread($handle, $chunk_size);
    ob_flush();
    flush();
}
fclose($handle);

安全下载控制

验证用户权限和文件路径,防止目录遍历攻击:

$base_dir = '/safe/directory/';
$requested_file = $_GET['file'];
$real_path = realpath($base_dir . $requested_file);

if (strpos($real_path, $base_dir) !== 0 || !file_exists($real_path)) {
    die('Invalid file');
}

断点续传支持

实现HTTP Range请求支持:

php怎么实现下载

$size = filesize($file_path);
$start = 0;
$end = $size - 1;

if (isset($_SERVER['HTTP_RANGE'])) {
    if (preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches)) {
        $start = intval($matches[1]);
        if (!empty($matches[2])) {
            $end = intval($matches[2]);
        }
    }
    header('HTTP/1.1 206 Partial Content');
    header("Content-Range: bytes $start-$end/$size");
}

header("Accept-Ranges: bytes");
header("Content-Length: " . ($end - $start + 1));

强制下载特定MIME类型

设置特定的Content-Type强制浏览器下载:

$mime_types = [
    'pdf' => 'application/pdf',
    'zip' => 'application/zip',
    // 添加更多MIME类型
];

$ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
if (array_key_exists($ext, $mime_types)) {
    header('Content-Type: ' . $mime_types[$ext]);
}

下载进度监控

使用输出缓冲和回调函数监控下载进度:

function readfile_chunked($filename, $chunk_size = 1024, $callback = null) {
    $handle = fopen($filename, 'rb');
    $total = filesize($filename);
    $sent = 0;

    while (!feof($handle)) {
        $buffer = fread($handle, $chunk_size);
        echo $buffer;
        $sent += strlen($buffer);
        if (is_callable($callback)) {
            call_user_func($callback, $sent, $total);
        }
        ob_flush();
        flush();
    }
    fclose($handle);
}

标签: php
分享给朋友:

相关文章

php实现websocket

php实现websocket

PHP 实现 WebSocket WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。PHP 可以通过多种方式实现 WebSocket 功能,以下是几种常见的方法: 使用 Ratc…

php实现队列

php实现队列

PHP实现队列的方法 队列是一种先进先出(FIFO)的数据结构,PHP可以通过多种方式实现队列功能。 使用数组模拟队列 PHP数组可以模拟队列的基本操作,通过array_push和array_shi…

php实现接口

php实现接口

PHP 实现接口的方法 在 PHP 中,接口(Interface)用于定义一组方法的规范,而不实现具体功能。类可以实现一个或多个接口,并必须实现接口中定义的所有方法。 定义接口 接口使用 inter…

php实现静态

php实现静态

静态化实现方法 PHP实现静态化主要通过生成HTML文件或缓存机制来减少服务器动态解析的开销。以下是几种常见方法: 生成静态HTML文件 通过file_put_contents()将动态内容保存为H…

php 实现单链表

php 实现单链表

单链表的基本概念 单链表是一种线性数据结构,由节点组成,每个节点包含数据域和指向下一个节点的指针域。链表的头节点是访问整个链表的入口。 单链表的节点类实现 在PHP中,可以通过类来定义链表节点。每个…

php实现一个

php实现一个

PHP 实现一个简单的计算器 创建一个基本的计算器,支持加、减、乘、除运算。以下是一个完整的实现代码示例: <?php $result = ""; if ($_SERVER["REQUES…