PHP基础 文件上传下载 第十六天

第一个注意项:上传的时候方法必须要为post方法

第二个注意项:修改enctype

第三项:为了防止用户传过大的文件,我们通常会写上一个隐藏表单,MAX_FILE_SIZE,将其值设为value=byte单位的值,防止用户等待时间过长。这一项,现在无效。【bug

文件上传。

1,看数组结构   【本质上面,我们就是在操作这个数组】

2,判断文件是否有错误

3,判断文件大小

4, 判断文件后缀是否在准许的后缀

5,判断文件MIME类型

6,判断是否是上传文件

7,移动文件   [按照日期生成子目录来保存文件,产生随机的文件名]




1.看数组结构:

 


$_FILES['userfile']['name']

客户端机器文件的原名称。      

$_FILES['userfile']['type']

文件的 MIME 类型,如果浏览器提供此信息的话。一个例子是“image/gif”。不过此       MIME 类型在 PHP 端并不检查,因此不要想当然认为有这个值。      

$_FILES['userfile']['size']

已上传文件的大小,单位为字节。      

$_FILES['userfile']['tmp_name']

文件被上传后在服务端储存的临时文件名。      

$_FILES['userfile']['error']

和该文件上传相关的错误代码。此项目是在       PHP 4.2.0 版本中增加的。




2.判断错误


如果无错,返回一个0,自动类型转换为bool值的假

1,我们可以强制取反  

2,我们可以显示错误,有错误就停止上传,如果无错误,就继续执行上传段代码

错误为0 无错

1 超过了php.ini当中的max_upload_size这一项准许的值

通常情况下为2M,但是,可以手动修改。不能超过POST最大准许大小

post_max_size = 8M  不要超过了内存准许的大小

php可以使用的内存限制  memory_limit = 128M

2 超过了表单的MAX_FILE_SIZE指定的大小

3 部份文件被上传

4 没有文件被上传

6     找不到临时文件夹  upload_tmp_dir = 手动指定临时文件夹所在的目录

7 文件写入失败  




3.判断文件大小




4.判断后缀



5.判断MIME



6.Is_uploaded_file  传进上传的临时文件,判断这是不是我PHP上传的文件



7.Move_uploaded_file移动上传文件(临时文件路径, 新路径和新名)






文件下载

1, 告诉浏览器类型

2, 告诉浏览器这是附件

3, 告诉浏览器大小   [可选]

4, 读取并输出文件内容   readfile








文件上传


form.html

<form action="up.php" method="post" enctype="multipart/form-data"> 

    <input type="file" name="jijing" /> 

    <input type="hidden"  name="MAX_FILE_SIZE" value="1000000" />
    <input type="submit" value="上传"> 

</form>


up.php

<?php
    echo '<pre>';
    var_dump($_FILES);
    echo '</pre>'; 

    if(!$_FILES['file']['error']){ 

        //无错误,继续执行文件上传
        //设置准许上传的字节数为1M
        $maxSize=1000000;
        //准许的后缀
        $allowSub=array('jpg','jpeg','gif','png','bmp');
        $allowMime=array('image/jpeg','image/jpg','image/pjpeg','image/png','image/x-png','image/gif','image/wbmp'); 

        if($maxSize<$_FILES['file']['size']){
            exit('文件大小超过了1M,禁止上传');
        }
        $arr=explode('.',$_FILES['file']['name']);
        $subfix=array_pop($arr);    // $sub=$arr[count($arr)-1]; 

        if(!in_array($subfix,$allowSub)){
            exit('文件后缀不准许');
        } 

        if(!in_array($_FILES['file']['type'],$allowMime)){
            exit('文件类型不准许');
        } 

        //time()  unix
        //
        //time().'_'.mt_rand(0,10000).'.'.$subfix;
        //
        //uniqid().'.'.$subfix
        //
        // 

        if(is_uploaded_file($_FILES['file']['tmp_name'])){ 

            $path='upload/'.date('Y').'/'.date('m').'/'.date('d').'/'; 

            if(!file_exists($path)){
                mkdir($path,0777,true);
            } 

            if(move_uploaded_file($_FILES['file']['tmp_name'],$path.uniqid().'.'.$subfix)){ 

                echo '上传成功';
            }else{
                echo '上传失败';
            }
        } 

    }else{
        //有错误 

        switch($_FILES['file']['error']){
            case 1: 

                $string='上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。 ';
                break;
            case 2:
                $string='上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。';
                break;
            case 3:
                $string='文件只有部分被上传';
                break;
            case 4:
                $string='没有文件被上传';
                break;
            case 6:
                $string='找不到临时文件夹。';
                break;
            case 7:
                $string='无法写入临时文件';
                break;
        }
        exit($string); 

    } 

?>

多文件上传

<form action="duo.php" method="post" enctype="multipart/form-data"> 

    <input type="file" name="jijing[]" />
    <input type="file" name="jijing[]" />
    <input type="file" name="jijing[]" />
    <input type="file" name="jijing[]" />
    <input type="file" name="jijing[]" /> 

    <input type="hidden"  name="MAX_FILE_SIZE" value="1000000" />
    <input type="submit" value="上传"> 

</form>

duo.php

<?php
echo '<pre>';
var_dump($_FILES);
echo '</pre>'; 

for($i=0;$i<count($_FILES['jijing']['name']);$i++){
move_uploaded_file($_FILES['jijing']['tmp_name'][$i],'upload/'.$_FILES['jijing']['name'][$i]);
}
?>

文件下载

<?php
//echo '<a href="mn.php">美女</a>';  直接ECHO 会显示而不会下载
/*
//告诉MIME类型
header('content-type:image/jpeg');
//附件及文件名
header('content-disposition:attachment;filename="nm.jpg"');
header('content-length:'.filesize('nm.jpg'));
readfile('nm.jpg'); 

header('content-type:text/html');
//附件及文件名
header('content-disposition:attachment;filename="up.php"');
//header('content-length:'.filesize('nm.jpg'));
readfile('up.php'); 

 */
header('content-type:application/vnd.ms-excel');
//附件及文件名
header('content-disposition:attachment;filename="gh.xls"');
//header('content-length:'.filesize('nm.jpg'));
//readfile('nm.jpg'); 

echo '<table width="800" border="1">';
for($i=0;$i<10;$i++){
    if($i%2){
        echo '<tr>';
    }else{
        echo '<tr bgcolor="red">';
    }
    for($j=0;$j<10;$j++){
        echo '<td>';
        echo $i*10+$j;
        echo '</td>';
    }
    echo '</tr>';
}
echo '</table>'; 

?>

apache mod_xendfile 文件下载

<?php

 $path_to_xlxz_file = "/img/xlxz.org/xlxz.bin";
 if ($user->isLoggedIn())
 {
     header("X-Sendfile: $path_to_xlxz_file");
     header("Content-Type: application/octet-stream");
     header("Content-Disposition: attachment; filename=xlxz.bin");
     exit;
 }
?>
<h1>没有权限</h1>
 <p>请先登录!</p>

nginx X-Accel-Redirect 文件下载

1. 在配置文件中做以下设定,internal 表示这个路径只能在 Nginx 内部访问.

location /img/ {
            internal;
            root  /some/path;
}

2.  PHP 发送 X-Accel-Redirect 给 Nginx:

<?php
  $filePath = '/img/xlxz.org/xlxz.img';
  header('Content-type: application/octet-stream');
  header('Content-Disposition: attachment; filename="' . basename($file) . '"');
  //让Xsendfile发送文件
  header('X-Accel-Redirect: '.$filePath);

3.  这样用户就会下载到 /some/path/img/xlxz.org/xlxz.img 这个路径下的文件。

4.  如果你想发送的是 /some/path/xlxz.org/xlxz.img 文件,那么 Nginx 配置

location /img/ {
  internal;
  alias  /some/path/; # 注意最后的斜杠
}