11.文件上传和下载

文件上传

客户端上传设置

  • 在B/S程序中文件上传已经成为一个常用功能。其目的是客户可以通过浏览器(Browser)将文件上传到服务器(Server)上的指定目录。

  • PHP中文件上传的基础知识:
    客户端form表单
    服务器端对上传文件的操作

客户端文件上传的form表单:
<html>
    <head><title>文件上传</title></head>
    <body>
        <form action="upload.php"  method="post"  enctype="multipart/form-data">
            <input type="hidden" name="MAX_FILE_SIZE" value="1000000">
            选择文件:<input type="file" name="myfile">
            <input type="submit" value="上传文件">
        </form>
    </body>
</html>

注意几个特征属性:

  • POST方法:
    表单最常用的功能,向目标页面传递变量,我们在上传文件的时候,会在表单中设置相应的属性,来完成文件的传递

  • enctype="multipart/form-data"
    这样服务器就会知道,我们要传递一个文件,这样服务器可以知道上载的文件带有常规的表单信息。

  • MAX_FILE_SIZE
    此字段必须在文件输入字段之前,控制最大的传递文件的大小(字节)

  • 设置浏览器文件输入浏览按钮

<input type="file" name="userfile">

在服务器端通过PHP处理上传

上传文件的接收和处理是通过PHP脚本来处理的,具体需要通过以下三个方面信息:

  • 设置PHP配置文件中的指令:用于精细地调节PHP的文件上传功能。
PHP配置文件中与文件上传有关的选项:
指令名 默认值 功能描述
file_uploads ON 是否开启文件上传
upload_max_filesize 2M 限制PHP处理上传文件大小的最大值,此值必须小于post_max_size
post_max_size 8M 限制通过POST方法可以接受信息的最大值,也就是整个POST请求的提交值。此值必须大于upload_max_filesize
upload_tmp_dir NULL 上传文件存放的临时路径,可以是绝对路径。默认NULL则使用系统的临时目录
  • $_FILES多维数组:用于存储各种与上传文件有关的信息,其他数据还是使用$_POST获取。
超级全局数组$_FILES
  • $_FILES["myfile"]["name"]中的值是:
    客户端文件系统的文件的名称
  • $_FILES["myfile"]["type"]中的值是:
    客户端传递的文件的类型
  • $_FILES["myfile"]["size"]中的值是:
    文件的字节的大小
  • $_FILES["myfile"]["tmp_name"]中的值是:
    文件被上传后在服务器存储的临时全路径
  • $_FILES["myfile"]["error"]中的值是:
    文件上传的错误代码-php 4.2以后增加的功能
存储在$_FILES["myfile"]["error"]中的值

伴随文件上传时产生的错误信息代码是在PHP4.2.0版本中引入的,具体如下:

  • 值为0:表示没有发生任何错误。对应常量的值 UPLOAD_ERR_OK

  • 值为1:表示上传文件的大小超出了约定值。文件大小的最大值是在PHP配置文件中指定的,该指令是:upload_max_filesize。对应常量的值 UPLOAD_ERR_INI_SIZE

  • 值为2:表示上传文件大小超出了HTML表单隐藏域属性的MAX_FILE_SIZE元素所指定的最大值。对应常量的值 UPLOAD_ERR_FORM_SIZE

  • 值为3:表示文件只被部分上传。对应常量的值 UPLOAD_ERR_PARTIAL

  • 值为4:表示没有上传任何文件。对应常量的值 UPLOAD_ERR_NO_FILE

  • 值为6:表示找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。对应常量的值 UPLOAD_ERR_NO_TMP_DIR

  • 值为7:表示文件写入失败。PHP 5.1.0 引进。对应常量的值 UPLOAD_ERR_CANT_WRITE

常见的数据格式

文件类型 MIME类型
图片文件 image/gif,image/jpg,image/jpeg,image/png,image/x-png
纯文本和HTML text/txt,text/plain,text/html
二进制文件 application/octet-stream
音频格式 audio/basic
视频格式 video/mpeg
PHP的文件上传处理函数:用于上传文件的后续处理。

上传成功的文件会被放置到服务器端临时目录下,文件名是随机生成的临时文件名。

注意:该文件在程序执行完后将自动被删除掉。在删除前可以像本地文件一样操作。

文件上传处理函数:

  • is_uploaded_file —判断文件是否是通过 HTTP POST 上传的
    格式:bool is_uploaded_file ( string $filename )
  • move_uploaded_file — 将上传的文件移动到新位置
    格式:bool move_uploaded_file ( string $filename , string $destination )

注意:如果目标文件已经存在,将会被覆盖。

上传代码示例

<?php
    $allowtype = array("gif", "png", "jpg");   //设置充许上传的类型为gif, png和jpg
    $size = 1000000;                           //设置充许大小为1M(1000000字节)以内的文件
    $path = "./uploads";                       //设置上传后保存文件的路径
    
    //1. 判断文件是否可以成功上传到服务器,$_FILES['myfile']['error'] 为0表示上传成功
    if($_FILES['myfile']['error'] > 0) {    
        echo '上传错误: ';
        switch ($_FILES['myfile']['error']) {
            case 1:  die('上传文件大小超出了PHP配置中的约定值:upload_max_filesize');  
            case 2:  die('上传文件大小超出了表单中的约定值:MAX_FILE_SIZE');  
            case 3:  die('文件只被部分上载'); 
            case 4:  die('没有上传任何文件'); 
            case 6:  die('找不到临时文件夹');
            case 7:  die('文件写入失败');
            default: die('末知错误');
        }
    } 
    //2. 判断上传的文件是否为充许的文件类型,通过文件的后缀名
    $hz = array_pop(explode(".", $_FILES['myfile']['name']));
    //3.通过判断文件的后缀方式,来决定文件是否是充许上传的文件类型
    if(!in_array($hz, $allowtype)) {
        die("这个后缀是<b>{$hz}</b>,不是充许的文件类型!");
    }
    //4. 判断上传的文件是否为充许大小
    if($_FILES['myfile']['size'] > $size ) {
        die("超过了充许的<b>{$size}</b>字节大小");
    }
    //5. 为了系统安全,也为了同名文件不会被覆盖,上传后将文件名使用系统定义
    $filename = date("YmdHis").rand(100,999).".".$hz;
    //6. 判断是否为上传文件
    if (is_uploaded_file($_FILES['myfile']['tmp_name'])) { 
        if (!move_uploaded_file($_FILES['myfile']['tmp_name'], $path.'/'.$filename)) {  
            die('问题: 不能将文件移动到指定目录。');
        }
    }else{
        die("问题: 上传文件{$_FILES['myfile']['name']}不是一个合法文件: ");
    }
    //7. 如果文件上传成功则输出
    echo "文件{$upfile}上传成功,保存在{$path}中,大小为{$_FILES['myfile']['size']}字节";   
?>

多文件上传

当需要上传多个文件的情况,有两种实现的解决方法:

  • 使用不同的表单元素
<input type="file" name="file_a">
<input type="file" name="file_b">
<input type="file" name="file_b">
  • 使用数组格式的表单元素
<input type="file" name="file[]">
<input type="file" name="file[]">
<input type="file" name="file[]">

文件下载

<?php
 //文件下载练习
$filename="./upload/aa.png";
$basename=pathinfo($filename);
header("Content-Type: image/png"); //指定下载文件类型的
header("Content-Disposition:attachment;filename=".                      $basename["basename"]);
//指定下载文件的描述信息
header("Content-Length:".filesize($filename));  //指定文件大小的
readfile($filename);//将内容输出,以便下载。
?>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容