Php中文件下载功能实现超详细流程分析_php技巧

客户端从服务端下载文件的流程分析:

浏览器发送一个请求,请求访问服务器中的某个网页(如:down.php),该网页的代码如下。
服务器接受到该请求以后,马上运行该down.php文件
运行该文件的时候,必然要把将要被下载的文件读入内存当中(这里是圣诞狂欢.jpg这张图片),这里通过fopen()函数完成该动作
注意:任何有关从服务器下载的文件操作,必然需要先在服务端将文件读入内存当中

现在文件已经在内存当中了,这是需要从内存当中读取文件,通过fread()函数完成该动作
需要注意的是,如果文件较大,文件应该是被分成多段返回给客户端的,并不是等文件在服务端全部读取完毕后,一次性返回给客户端,因为这样子会增加服务器的负荷。
所以我们需要在php代码中设置一次读取的字节数,比如我在下面的代码中通过$buffer=1024设置一次读取的字节数,每读取一次,就输出数据(即返回给浏览器)

流程图:

复制代码 代码如下:

<?php
header("Content-type:text/html;charset=utf-8");
// $file_name="cookie.jpg";
$file_name="圣诞狂欢.jpg";
//用以解决中文不能显示出来的问题
$file_name=iconv("utf-8","gb2312",$file_name);
$file_sub_path=$_SERVER['DOCUMENT_ROOT']."marcofly/phpstudy/down/down/";
$file_path=$file_sub_path.$file_name;
//首先要判断给定的文件存在与否
if(!file_exists($file_path)){
echo "没有该文件文件";
return ;
}
$fp=fopen($file_path,"r");
$file_size=filesize($file_path);
//下载文件需要用到的头
Header("Content-type: application/octet-stream");
Header("Accept-Ranges: bytes");
Header("Accept-Length:".$file_size);
Header("Content-Disposition: attachment; filename=".$file_name);
$buffer=1024;
$file_count=0;
//向浏览器返回数据
while(!feof($fp) && $file_count<$file_size){
$file_con=fread($fp,$buffer);
$file_count+=$buffer;
echo $file_con;
}
fclose($fp);
?>

几点注意事项:

header("Content-type:text/html;charset=utf-8")的作用:在服务器响应浏览器的请求时,告诉浏览器以编码格式为UTF-8的编码显示该内容
关于file_exists()函数不支持中文路径的问题:因为php函数比较早,不支持中文,所以如果被下载的文件名是中文的话,需要对其进行字符编码转换,否则file_exists()函数不能识别,可以使用iconv()函数进行编码转换
$file_sub_path() 我使用的是绝对路径,执行效率要比相对路径高
Header("Content-type: application/octet-stream")的作用:通过这句代码客户端浏览器就能知道服务端返回的文件形式
Header("Accept-Ranges: bytes")的作用:告诉客户端浏览器返回的文件大小是按照字节进行计算的
Header("Accept-Length:".$file_size)的作用:告诉浏览器返回的文件大小
Header("Content-Disposition: attachment; filename=".$file_name)的作用:告诉浏览器返回的文件的名称
以上四个Header()是必需的
fclose($fp)可以把缓冲区内最后剩余的数据输出到磁盘文件中,并释放文件指针和有关的缓冲区

时间: 2024-09-20 15:40:47

Php中文件下载功能实现超详细流程分析_php技巧的相关文章

php中让人头疼的浮点数运算分析_php技巧

本文实例分析了php中让人头疼的浮点数运算.分享给大家供大家参考,具体如下: 在做电商的时候,计算价格是免不了的,然后发现了php的一个坑,口算应该正确的值,php运算出来会跟你不一样 请看下面的代码: $price=69.1; $count=100; $total=$price*$count-6910; echo $total; 你猜一下变量$total的值是多少,运行一下这个代码输出:-9.09494701773E-13 怎么解决这个问题呢? 使用round函数 代码修改成: $price=

PHP 强制性文件下载功能的函数代码(任意文件格式)_php技巧

复制代码 代码如下: /******************** *@file - path to file */ function force_download($file) { if ((isset($file))&&(file_exists($file))) { header("Content-length: ".filesize($file)); header('Content-Type: application/octet-stream'); header('

PHP中static关键字原理的学习研究分析_php技巧

看PHP手册的时候发现了下面这样一段代码: 复制代码 代码如下: <?php function Test() { static $count = 0; $count++; echo $count; if ($count < 10) { Test(); } $count--; } ?> 执行结果如下: 这是一个递归的函数,声明的静态变量count记录次数,输出1~10. 我在看的时候有个疑惑,递归调用的时候 static $count = 0; 语句会重复执行,这为什么不会导致count变

PHP中mysqli_affected_rows作用行数返回值分析_php技巧

本文实例分析了PHP中mysqli_affected_rows作用行数返回值.分享给大家供大家参考.具体分析如下: mysqli中关于update操作影响的行数可以有两种返回形式: 1. 返回匹配的行数 2. 返回影响的行数 默认情况下mysqli_affected_rows返回的值为影响的行数,如果我们需要返回匹配的行数,可以使用mysqli_real_connect函数进行数据库连接的初始化,并在函数的flag参数位加上: MYSQLI_CLIENT_FOUND_ROWS return nu

PHP7.1新功能之Nullable Type用法分析_php技巧

本文实例分析了PHP7.1新功能之Nullable Type用法.分享给大家供大家参考,具体如下: 在 PHP5 时代,PHP 的参数已经支持 type hint(除了基本类型),想必大家应该很熟悉:后来 PHP7 时代来临,PHP 也可以指定返回值的类型(以及基本类型的 type hint).但我们可能还有一种需求:除了指定的 type hint,参数或者返回值也能定义可以为 null,举个例子,假如我们有一个 UserRepository 类,有一个方法叫 find($id),此方法可返回一

PHP中抽象类和抽象方法概念与用法分析_php技巧

本文实例讲述了PHP中抽象类和抽象方法.分享给大家供大家参考,具体如下: 一.抽象关键字 :abstract 抽象就是无法确切的说明,但又有一定的概念或者名称,在PHP中声明一个抽象类或者方法我们需要使用adstract关键字. 二.抽象方法和抽象类的定义 一个类中至少有一个方法是抽象的,我们称之为抽象类.所以如果定义抽象类首先定义抽象方法. abstract class class1{ abstract function fun1(); -- } 1.类中至少有一个抽象方法2.抽象方法不允许有

php中get_meta_tags()、CURL与user-agent用法分析_php技巧

本文实例分析了php中get_meta_tags().CURL与user-agent用法.分享给大家供大家参考.具体分析如下: get_meta_tags()函数用于抓取网页中<meta name="A" content="1"><meta name="B" content="2">形式的标签,并装入一维数组,name为元素下标,content为元素值,上例中的标签可以获得数组:array('A'=&g

php中注册器模式类用法实例分析_php技巧

本文实例讲述了php中注册器模式类用法.分享给大家供大家参考,具体如下: 注册器读写类 Registry.class.php <?php /** * 注册器读写类 */ class Registry extends ArrayObject { /** * Registry实例 * * @var object */ private static $_instance = null; /** * 取得Registry实例 * * @note 单件模式 * * @return object */ pu

PHP中isset与array_key_exists的区别实例分析_php技巧

本文实例讲述了PHP中isset与array_key_exists的区别.分享给大家供大家参考.具体分析如下: 1.对于数组值的判断不同,对于值为null或''或false,isset返回false,array_key_exists返回true: 2. 执行效率不同,isset是内建运算符,array_key_exists是php内置函数,isset要快一些.请参考:PHP 函数实现原理及性能分析 3.当用isset访问一个不存在索引数组值时,不会引起一个E_NOTICE的php错误消息: 4.