当前位置:首页 > PHP

php怎么实现下载

2026-01-28 23:28:11PHP

实现文件下载的基本方法

在PHP中实现文件下载通常通过设置HTTP头信息强制浏览器触发下载行为。核心代码如下:

$file_path = '/path/to/file.pdf';
$file_name = 'document.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;

处理大文件下载

对于大文件下载需要优化内存使用,避免直接读取整个文件:

$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/download/directory/';
$requested_file = $_GET['file'];
$real_path = realpath($base_dir . $requested_file);

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

断点续传支持

实现HTTP Range请求支持断点续传:

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

if (isset($_SERVER['HTTP_RANGE'])) {
    preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
    $start = (int)$matches[1];
    $end = isset($matches[2]) ? (int)$matches[2] : $file_size - 1;

    header('HTTP/1.1 206 Partial Content');
    header('Content-Range: bytes '.$start.'-'.$end.'/'.$file_size);
}

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

$handle = fopen($file_path, 'rb');
fseek($handle, $start);

下载统计与限速

添加下载统计和速度限制功能:

$speed_limit = 1024 * 50; // 50KB/s
$start_time = microtime(true);
$bytes_sent = 0;

while (!feof($handle) && connection_status() == 0) {
    $buffer = fread($handle, $speed_limit);
    echo $buffer;
    $bytes_sent += strlen($buffer);

    $elapsed = microtime(true) - $start_time;
    $should_take = $bytes_sent / $speed_limit;
    if ($elapsed < $should_take) {
        usleep(($should_take - $elapsed) * 1000000);
    }

    ob_flush();
    flush();
}

常见问题处理

处理文件名编码问题:

php怎么实现下载

$user_agent = $_SERVER['HTTP_USER_AGENT'];
$encoded_filename = rawurlencode($file_name);

if (preg_match('/MSIE|Trident/i', $user_agent)) {
    header('Content-Disposition: attachment; filename="'.iconv('UTF-8', 'CP932//IGNORE', $file_name).'"');
} elseif (preg_match('/Firefox/i', $user_agent)) {
    header('Content-Disposition: attachment; filename*=UTF-8\'\''.$encoded_filename);
} else {
    header('Content-Disposition: attachment; filename="'.$file_name.'"');
}

标签: php
分享给朋友:

相关文章

git php实现

git php实现

Git 与 PHP 的集成实现 使用 PHP 执行 Git 命令 通过 PHP 的 exec()、shell_exec() 或 passthru() 函数可以直接调用 Git 命令,适用于服务器端操作…

php 队列的实现

php 队列的实现

PHP 队列的实现方法 使用数据库实现队列 创建一个数据表存储队列任务,包含任务ID、状态、创建时间等字段。通过SQL语句实现任务的入队和出队操作。 // 入队操作 INSERT INTO queu…

php https实现

php https实现

PHP 中实现 HTTPS 的方法 在 PHP 中实现 HTTPS 主要通过配置服务器和编写代码来确保通信的安全性。以下是几种常见的方法: 配置服务器支持 HTTPS 确保服务器已安装 SSL/T…

php实现投票

php实现投票

PHP实现投票功能 数据库设计 创建数据库表存储投票数据,例如: CREATE TABLE `votes` ( `id` int(11) NOT NULL AUTO_INCREMENT,…

php实现分享功能实现

php实现分享功能实现

实现PHP分享功能的方法 在PHP中实现分享功能可以通过多种方式完成,以下是一些常见的实现方法: 使用社交媒体分享按钮 社交媒体平台如Facebook、Twitter、LinkedIn等提供了现成…

php实现批量删除

php实现批量删除

PHP 实现批量删除的方法 表单设计与前端交互 在 HTML 表单中使用复选框(checkbox)让用户选择要删除的项。每个复选框的 name 属性设置为数组形式(如 items[]),以便 PHP…