Linfinity

Never say never.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

php实现文件上传、下载、分页

Posted on 2019-01-07 13:28  Linfinity  阅读(321)  评论(0)    收藏  举报

一、PHP文件上传

1、文件上传的原理说明

文件上传,其实也是通过表单提交的表单提交的数据分为如下两种:

1)字节流数据:输入框、单选框复选框、多行文本域等都是通过字节的数据传输到服务器服务器通过$_GET  $_POST接收

2)二进制文件流的形式;当需要提交一些文件的时候,由于文件采用的二进制的形式进行编码,所以需要先将二进制文件转码,然后再提交到服务器

提交的时候,需要通过input type=”file” 文件域上传

服务器接收的时候,通过$_FILES进行接收

注意如何将表单数据,以二进制流的形式进行传输,必须在表单form标签增加一个属性:enctype=”multipart/form-data”

 

2、MIME类型详解

多用途internet邮件扩展,mime类型的出现,跟着电子邮件出现的

早期,发送电子邮件的时候里面可能会附带一些附件,计算机系统根据附件的类型找到对应的设备打开,例如:传输的视频,就会找到视频播放器去打开,如果传输的网页文件,那么会自动使用浏览器去打开

MIME类型,包括2部分:第一个部分是该文件所属的一个大类第二个部分是文件细节小类例如:

text/html,属于文本文件,html这样的文本文件

image/jpg,属于像大类jpg这种类型的图像

 

tmp_name详解:

tmp------ temp----temporary,该单词的意思是临时的

 

文件上传的原理:

我们点击提交表单时file文件域里面的文件,先上传到临时目录(可以php的配置文件中设置)默认的临时目录是c:/windows/temp,如果需要持久的保存,需要通过php的函数move_uploaded_file()移动指定的位置,如果不移动,当php脚本执行结束,临时文件就会消失

 

代码演示一下:

由于php脚本执行的太,为了看到效果,我们让php脚本休眠10钟:

提交表单之后,就会在c:/windows/temp目录下面看到这个临时文件

 

为了不让临时文件消失,我们需要在脚本结束之前,将该临时文件移动到服务器

使用phpmove_uploaded_file()函数进行移动的 注意:若使用move_uploaded_file()移动图片并且返回true但是图片不能正常访问,请先打开c:/windows/temp目录获取权限!!!

 

3、文件上传类

上传一个文件我们必须要对文件做一些验证,如文件大小、文件类型等,为了方便每次使用我们可以将其封装成一个上传文件工具类。

 

<?php

//上传文件工具类  by dominik
class Uploader{
    //上传根目录
    private $destination = 'uploads/';
    //允许上传文件类型
    private $allow_upload_file_type = array('image/jpeg','image/jpg','image/png');
    //允许上传文件大小
    private $max_upload_size = 1024*500;
    //文件名前缀
    private $prefix = 'fk_';
    
    public function __set($prop_name,$prop_val){
        if(property_exists($this, $prop_name)){
            $this->$prop_name = $prop_val;
        }
    }
    
    public function __get($prop_name){
        if(property_exists($this, $prop_name)){
            return $this->$prop_name;
        }
    }
      
    public function upload($file){
        $filename = $file["tmp_name"];
        
        //1.上传文件大小验证
        if($file["size"]>$this->max_upload_size){
            echo '文件过大,无法上传';
            exit;
        }
        
        //2.设计不重复文件名
        $sub_dir = $this->destination . date('Ymd');
        
        if(!is_dir($sub_dir)){
            mkdir($sub_dir);
        }
        
        $destination = $sub_dir . '/' . uniqid($this->prefix,true) . strrchr($file["name"], '.');
        
        //3.设置可上传类型;
        
        $finfo = new finfo(FILEINFO_MIME_TYPE);
        
        if(!in_array($finfo->file($filename), $this->allow_upload_file_type)){
            echo '文件格式有误,无法上传';
            exit;
        }
        
        $flag = move_uploaded_file($filename, $destination);
        
        if($flag){
            return $destination;
        }else{
                return false;
            }
        
    }
    
    
    
    
    
}
Uploader.class.php

 

 

 

 

二、PHP文件下载

1、文件下载方法

如果下载的文件较多、文件大,通常就使用百度云,如果下载的文件小、文件少的,通常会使用php进行下载

 

2、通过php下载文件的原理

通过php读取下载的文件资源,读取到这些资源之后,再将其保存到文件

服务器文件中,读取文件的内容,再告诉浏览器附件的形式来接收这些内容

设置响应头四句固定代码:

   //告诉浏览器我向你回应的内容是文件请保存
    //返回的文件
    header("Content-type: application/octet-stream");
    //按照字节大小返回
    header("Accept-Ranges: bytes");
    //显示文件大小
    header("Content-Length: $file_size");
    //这里客户端的弹出对话框,对应的文件名
    header("Content-Disposition: attachment; filename=".$file);

 

 

三、分页组件

1、分页工具类

<?php
class Page
{
    private $total_pages = 100; //总的记录数
    private $pagesize = 6;      //每页显示的记录数
    private $now_page = 1;      //当前是第几页
    private $url = '';          //跳转到哪个页面
    
    public function __set($p,$v)
    {
        if(property_exists($this, $p)){
            $this->$p = $v;
        }
    }
    public function __get($p)
    {
        return $this->$p;
    }
    
    //创建分页导航条的方法
    public function create()
    {
        //首页导航按钮
        $first_active = $this->now_page == 1 ? 'active' :'';
        //将来给每一个超链接增加page参数,保存当前的页数
        $url = $this->url.'?page=';
        $first = 1;
        
        $page = <<<HTML
            <ul class="pagination">
            <li class="$first_active"><a href="$url$first">首页</a></li>
HTML;
        //遍历中间的分页导航按钮
        $total_pages = ceil($this->total_pages / $this-> pagesize);
        //显示当前页的前3页、后3页,例如:当前页是5页               2 3 4 5 6 7 8
        //特殊情况,我们特殊处理,例如:
        
        for($i=$this->now_page-3;$i<=$this->now_page+3;$i++){
            if($i<2 || $i>$total_pages-1){
                continue;
            }
            $active = $this->now_page == $i ? 'active':'';
            $page .= <<<HTML
            <li class="$active"><a href="$url$i">$i</a></li>
HTML;
        }
        
        //尾页导航按钮
        $last_active = $this->now_page == $total_pages ? 'active':'';
        $page .= <<<HTML
            <li class="$last_active"><a href="$url$total_pages">尾页</a></li>
        </ul>
HTML;
        return $page;
    }
}
Page.class.php

2、使用案例

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="css/bootstrap.css">
    </head>
    <body>
        <?php 
            //引入DAOMySQLiclass.php类
            require_once 'DAOMySQLi.class.php';
            
            $option = array(
                'host'      =>  '127.0.0.1',
                'user'      =>  'root',
                'pwd'       =>  'root',
                'port'      =>  3306,
                'db'        =>  'php_7',
                'charset'   =>  'utf8'
            );
            $dao = DAOMySQLi::getSingleton($option);
            $sql = "SELECT count(*) as total FROM goods";
            $result = $dao -> fetchOne($sql);
            
        
        
          require 'Page.class.php';
          $page = new Page();
          
          //当前是第几页
          $page -> now_page = isset($_GET['page'])?$_GET['page']:1;
          //每页显示几条记录
          $page -> pagesize = 5;
          //总的记录数
          $page -> total_pages = $result['total'];
          
          echo $page -> create();
          
          
          //查询商品列表
          
            //拼接sql语句查询所有的商品信息
            /*
             * now      offset      pagesize
             *  1         0             5
             *  2         5             5
             *  3         10            5
             */
            $offset = ($page -> now_page - 1)*$page->pagesize;
            $size = $page -> pagesize;
            
            $sql = "SELECT * FROM goods limit $offset,$size";
            $goods_list = $dao -> fetchAll($sql);
            
            //加载商品列表的模板(模子)
            require_once '2.template.php';
          
        ?>
    </body>
</html>
View Code

 

注:需导入bootstrap!