PHP实现文件上传和下载的示例代码

目录

1.效果图

PHP实现文件上传和下载的示例代码

PHP实现文件上传和下载的示例代码

2.首先是封装好的图片类(缩放及生成水印)

1.GDBasic.php

<?php
/**
 * GDBasic.php
 * description GD基础类
 */
 
namespace test\\Lib;
 
 
class GDBasic
{
    protected static $_check =false;
 
    //检查服务器环境中gd库
    public static function check()
{
        //当静态变量不为false
        if(static::$_check)
        {
            return true;
        }
 
        //检查gd库是否加载
        if(!function_exists(\"gd_info\"))
        {
            throw new \\Exception(\'GD is not exists\');
        }
 
        //检查gd库版本
        $version = \'\';
        $info = gd_info();
        if(preg_match(\"/\\\\d+\\\\.\\\\d+(?:\\\\.\\\\d+)?/\", $info[\"GD Version\"], $matches))
        {
            $version = $matches[0];
        }
 
        //当gd库版本小于2.0.1
        if(!version_compare($version,\'2.0.1\',\'>=\'))
        {
            throw new \\Exception(\"GD requires GD version \'2.0.1\' or greater, you have \" . $version);
        }
 
        self::$_check = true;
        return self::$_check;
    }
}

2.Image.php

<?php
/**
 * Image.php
 * description 图像类
 */
 
namespace test\\Lib;
 
require_once \'GDBasic.php\';
 
class Image extends GDBasic
{
    protected $_width;
    protected $_height;
    protected $_im;
    protected $_type;
    protected $_mime;
    protected $_real_path;
 
    
    public function __construct($file)
{
        //检查GD库
        self::check();
        $imageInfo = $this->createImageByFile($file);
        $this->_width = $imageInfo[\'width\'];
        $this->_height = $imageInfo[\'height\'];
        $this->_im = $imageInfo[\'im\'];
        $this->_type = $imageInfo[\'type\'];
        $this->_real_path = $imageInfo[\'real_path\'];
        $this->_mime = $imageInfo[\'mime\'];
    }
 
 
    /**
     * 根据文件创建图像
     * @param $file
     * @return array
     * @throws \\Exception
     */
    public function createImageByFile($file)
{
        //检查文件是否存在
        if(!file_exists($file))
        {
            throw new \\Exception(\'file is not exits\');
        }
 
        //获取图像信息
        $imageInfo = getimagesize($file);
        $realPath = realpath($file);
        if(!$imageInfo)
        {
            throw new \\Exception(\'file is not image file\');
        }
 
        switch($imageInfo[2])
        {
            case IMAGETYPE_GIF:
                $im = imagecreatefromgif($file);
                break;
            case IMAGETYPE_JPEG:
                $im = imagecreatefromjpeg($file);
                break;
            case IMAGETYPE_PNG:
                $im = imagecreatefrompng($file);
                break;
            default:
                throw  new \\Exception(\'image file must be png,jpeg,gif\');
        }
 
        return array(
            \'width\'     => $imageInfo[0],
            \'height\'    => $imageInfo[1],
            \'type\'      => $imageInfo[2],
            \'mime\'      => $imageInfo[\'mime\'],
            \'im\'        => $im,
            \'real_path\' => $realPath,
        );
 
    }
 
    /**
     * 缩略图
     * @param  int $width 缩略图高度
     * @param  int $height 缩略图宽度
     * @return $this
     * @throws \\Exception
     */
    public function resize($width, $height)
{
        if(!is_numeric($width) || !is_numeric($height))
        {
            throw new \\Exception(\'image width or height must be number\');
        }
        //根据传参的宽高获取最终图像的宽高
        $srcW = $this->_width; 
        $srcH = $this->_height;
 
        if($width <= 0 || $height <= 0)
        {
            $desW = $srcW;//缩略图高度
            $desH = $srcH;//缩略图宽度
        }
        else
        {
            $srcP = $srcW / $srcH;//宽高比
            $desP = $width / $height; 
 
            if($width > $srcW)
            {
                if($height > $srcH)
                {
                    $desW = $srcW;
                    $desH = $srcH;
                }
                else
                {
                    $desH = $height;
                    $desW = round($desH * $srcP);
                }
            }
            else
            {
                if($desP > $srcP)
                {
                    $desW = $width;
                    $desH = round($desW / $srcP);
                }
                else
                {
                    $desH = $height;
                    $desW = round($desH * $srcP);
                }
            }
        }
 
        //PHP版本小于5.5
        if(version_compare(PHP_VERSION, \'5.5.0\', \'<\'))
        {
            $desIm = imagecreatetruecolor($desW, $desH);
            if(imagecopyresampled($desIm, $this->_im, 0, 0, 0, 0, $desW, $desH, $srcW, $srcH))
            {
                imagedestroy($this->_im);
                $this->_im = $desIm;
                $this->_width = imagesx($this->_im);
                $this->_height = imagesy($this->_im);
            }
        }
        else
        {
            if($desIm = imagescale($this->_im, $desW, $desH))
            {
                $this->_im = $desIm;
                $this->_width = imagesx($this->_im);
                $this->_height = imagesy($this->_im);
            }
 
        }
 
        return $this;
    }
 
 
    /**
     * 根据百分比生成缩略图
     * @param int $percent 1-100
     * @return Image
     * @throws \\Exception
     */
    public function resizeByPercent($percent)
{
        if(intval($percent) <= 0)
        {
            throw new \\Exception(\'percent must be gt 0\');
        }
 
        $percent = intval($percent) > 100 ? 100 : intval($percent);
 
        $percent = $percent / 100;
 
        $desW = $this->_width * $percent;
        $desH = $this->_height * $percent;
        return $this->resize($desW, $desH);
    }
 
 
    /**
     * 图像旋转
     * @param $degree
     * @return $this
     */
    public function rotate($degree)
{
        $degree = 360 - intval($degree);
        $back = imagecolorallocatealpha($this->_im,0,0,0,127);
        $im = imagerotate($this->_im,$degree,$back,1);
        imagesavealpha($im,true);
        imagedestroy($this->_im);
        $this->_im = $im;
        $this->_width = imagesx($this->_im);
        $this->_height = imagesy($this->_im);
        return $this;
    }
 
 
    /**
     * 生成水印
     * @param file $water 水印图片
     * @param int $pct   透明度
     * @return $this
     */
    public function waterMask($water =\'\',$pct = 60 )
{
        //根据水印图像文件生成图像资源
        $waterInfo = $this->createImageByFile($water);
        imagecopymerge();
        //销毁$this->_im
        $this->_im = $waterInfo[\'im\'];
        $this->_width = imagesx($this->_im);
        $this->_height = imagesy($this->_im);
        return $this;
 
    }
 
 
 
    /**
     * 图片输出
     * @return bool
     */
    public function show()
{
        header(\'Content-Type:\' . $this->_mime);
        if($this->_type == 1)
        {
            imagegif($this->_im);
            return true;
        }
 
        if($this->_type == 2)
        {
            imagejpeg($this->_im, null, 80);
            return true;
        }
 
        if($this->_type == 3)
        {
            imagepng($this->_im);
            return true;
        }
    }
 
    /**
     * 保存图像文件
     * @param $file
     * @param null $quality
     * @return bool
     * @throws \\Exception
     */
    public function save($file, $quality = null)
{
        //获取保存目的文件的扩展名
        $ext = pathinfo($file, PATHINFO_EXTENSION);
        $ext = strtolower($ext);
        if(!$ext || !in_array($ext, array(\'jpg\', \'jpeg\', \'gif\', \'png\')))
        {
            throw new \\Exception(\'image save file must be jpg ,png,gif\');
        }
 
        if($ext === \'gif\')
        {
            imagegif($this->_im, $file);
            return true;
        }
        if($ext === \'jpeg\' || $ext === \'jpg\')
        {
            if($quality > 0)
            {
                if($quality < 1)
                {
                    $quality = 1;
                }
                if($quality > 100)
                {
                    $quality = 100;
                }
 
                imagejpeg($this->_im, $file, $quality);
            }
            else
            {
                imagejpeg($this->_im, $file);
            }
            return true;
        }
 
        if($ext === \'png\')
        {
            imagepng($this->_im, $file);
            return true;
        }
 
    }
}

style样式不是重点,先不放了

3.ajax类封装文件

let $ = new class {
 
    constructor()
    {
        this.xhr = new XMLHttpRequest();
        this.xhr.onreadystatechange = () => {
            if (this.xhr.readyState == 4 && this.xhr.status == 200) {
                // process response text
                let response = this.xhr.responseText;
                if (this.type == \"json\") {
                    response = JSON.parse(response);
                }
                this.callback(response);
            }
        }
    }
 
    get(url, parameters, callback, type = \"text\")
    {
        // url = test.php?username=zhangsan&age=20
        // parameters = {\"username\": \"zhangsan\", \"age\": 20}
        let data = this.parseParameters(parameters);
        if (data.length > 0) {
            url += \"?\" + data;
        }
        this.type = type;
        this.callback = callback;
        this.xhr.open(\"GET\", url, true);
        this.xhr.send();
    }
 
    post(url, parameters, callback, type = \"text\")
    {
        let data = this.parseParameters(parameters);
        this.type = type;
        this.callback = callback;
        this.xhr.open(\"POST\", url, true);
        this.xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");
        this.xhr.send(data);
    }
 
    parseParameters(parameters)
    {
        // username=zhangsan&age=20
        let buildStr = \"\";
        for (let key in parameters) {
            let str = key + \"=\" + parameters[key];
            buildStr += str + \"&\";
        }
        return buildStr.substring(0, buildStr.length - 1);
    }
};

1.index.php

<!DOCTYPE html>
<html lang=\"zh-CN\">
 
<head>
    <meta charset=\"utf-8\">
    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">
    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后!-->
    <title>文件上传和下载</title>
    <!-- Bootstrap -->
    <link href=\"style/css/bootstrap.min.css\" rel=\"external nofollow\"  rel=\"stylesheet\">
    <link href=\"style/css/site.min.css\" rel=\"external nofollow\"  rel=\"stylesheet\">
    <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css\" rel=\"external nofollow\" >
    <style>
        .projects .thumbnail .caption {
            height: auto;
            max-width: auto;
        }
        .image{
            margin:10px auto;
            border-radius:5px;
            overflow:hidden;
            border:1px solid #CCC;
        }
        .image .caption P{
            text-align: center;
        }
</style>
</head>
 
<body>
    <!--导航栏-->
    <div class=\"navbar navbar-inverse navbar-fixed-top\">
        <div class=\"container\">
            <div class=\"navbar-header\">
                <button class=\"navbar-toggle collapsed\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">
                  <span class=\"sr-only\">Toggle navigation</span>
                  <span class=\"icon-bar\"></span>
                  <span class=\"icon-bar\"></span>
                  <span class=\"icon-bar\"></span>
                </button>
                <a class=\"navbar-brand hidden-sm\" href=\"\" onclick=\" rel=\"external nofollow\" _hmt.push([\'_trackEvent\', \'navbar\', \'click\', \'navbar-首页\'])\">XX网</a>
            </div>
            <div class=\"navbar-collapse collapse\" role=\"navigation\">
                <ul class=\"nav navbar-nav\">
                    <li class=\"hidden-sm hidden-md\">
                        <a href=\"\" target=\" rel=\"external nofollow\"  rel=\"external nofollow\" _blank\"></a>
                    </li>
                    <li>
                        <a href=\"\" target=\" rel=\"external nofollow\"  rel=\"external nofollow\" _blank\"></a>
                    </li>
                </ul>
            </div>
        </div>
    </div>
    <!--导航栏结束-->
    <!--巨幕-->
    <div class=\"jumbotron masthead\">
        <div class=\"container\">
            <h1>文件上传下载</h1>
            <h2>实现文件的上传和下载功能</h2>
            <p class=\"masthead-button-links\">
                <form class=\"form-inline\" onsubmit=\"return false;\">
                    <div class=\"form-group\">
                        <input type=\"search\" class=\"form-control keywords\" id=\"exampleInputName2\" placeholder=\"输入搜索内容\" name=\"keywords\" value=\"\">
                        <button class=\"btn btn-default searchBtn\" type=\"submit\">搜索</button>
                        <button type=\"button\" class=\"btn btn-primary btn-default\" data-toggle=\"modal\" data-target=\"#myModal\">  上传  </button>
                    </div>
                </form>
            </p>
        </div>
    </div>
    <!--巨幕结束-->
    <!-- 模态框 -->
    <div class=\"modal fade\" id=\"myModal\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"myModalLabel\">
        <div class=\"modal-dialog\" role=\"document\">
            <form class=\"form-inline\" action=\"upload_class.php\" method=\"post\" enctype=\"multipart/form-data\">
                <input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"10240000\" />
                <div class=\"modal-content\">
                    <div class=\"modal-header\">
                        <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\"><span aria-hidden=\"true\">&times;</span></button>
                        <h4 class=\"modal-title\" id=\"myModalLabel\">上传图片</h4>
                    </div>
                    <div class=\"modal-body\">
                        <p>选择图片:</p><input type=\"file\" id=\"image\" name=\"test_pic[]\">
                        <br/>
                        <p>图片描述:</p><textarea class=\"form-control\" cols=\"75\" name=\"description\" id=\"info\"></textarea>
                        <br/><br/>
                        <p>
                          是否添加水印:
                          <select name=\"mark\">
                            <option value=\"1\">添加</option>
                            <option value=\"0\">不添加</option>
                          </select>
                        </p>
                        <br/>
                        <p>
                          图片宽度比例:
                            <select name=\"scale\">
                              <option value=\"800*600\">800*600</option>
                              <option value=\"600*450\">600*450</option>
                              <option value=\"400*300\">400*300</option>
                            </select>
                        </p>
                    </div>
                    <div class=\"modal-footer\">
                        <button type=\"submit\" class=\"btn btn-default\" name=\"submit\" id=\"submit\" onclick=\"show(this)\">上传</button>
                        <button type=\"reset\" class=\"btn btn-primary\">重置</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
    <!--模态框结束-->
 
    <div class=\"container projects\">
        <div class=\"projects-header page-header\">
            <h2>上传图片展示</h2>
            <p>将上传的图片展示在页面中</p>
        </div>
        <div class=\"row pic_body\">
            <!-- 使用js显示图片 -->
        </div>
        <!--分页-->
        <nav aria-label=\"Page navigation\" style=\"text-align:center\">
            <ul class=\"pagination pagination-lg\">
                <!-- 使用js显示页码 -->
            </ul>
        </nav>
    </div>
 
    <footer class=\"footer  container\">
        <div class=\"row footer-bottom\">
            <ul class=\"list-inline text-center\">
                <h4><a href=\"class.test.com\" rel=\"external nofollow\"  target=\"_blank\">class.test.com</a> | XX网</h4>
            </ul>
        </div>
    </footer>
 
    <!-- jQuery (necessary for Bootstrap\'s JavaScript plugins) -->
    <script src=\"style/js/jquery.min.js\"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src=\"style/js/bootstrap.min.js\"></script>
    <script type=\"text/JavaScript\">
        function show(){
          if(document.getElementById(\"image\").value == \'\'){
            alert(\'请选择图片\');
          }
          if(document.getElementById(\"info\").value == \'\'){
            alert(\'请输入图片描述\');
          }
        }
</script>
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src=\"https://code.jquery.com/jquery-3.2.1.slim.min.js\" integrity=\"sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN\" crossorigin=\"anonymous\"></script>
    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js\" integrity=\"sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q\" crossorigin=\"anonymous\"></script>
    <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js\" integrity=\"sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl\" crossorigin=\"anonymous\"></script>
    <script src=\"style/js/Ajax.js\"></script>
    <script>
        let pageNo = 1;
        let kws = \'\';
        let searchBtn = document.getElementsByClassName(\'searchBtn\')[0];
        searchBtn.onclick = function() {
            let search = document.getElementsByClassName(\'keywords\')[0];
            let keywords = search.value;
            requestData(pageNo, keywords);
            kws = keywords;
        };
 
        let requestPage = function(page) {
            requestData(page, kws);
            pageNo = page;
        };
 
 
        let requestData = function(page_number, keywords) {
            let pagination = document.getElementsByClassName(\'pagination\')[0];
            let pic_body = document.getElementsByClassName(\'pic_body\')[0];
            pic_body.innerHTML = \'<p style=\"text-align:center\"><i class=\"fa fa-spinner fa-spin\" style=\"font-size:24px\"></i> 加载中...</p>\';
            $.get(\'search.php\', {\"page\": page_number, \"keywords\": keywords}, function (res) {
                let divs = \'\';
                if (res.code == 1) {
                    // 请求成功
                    res.rows.forEach(function (item) {
                        let div = \'<div class=\"col-sm-6 col-md-3 col-lg-4\"><div class=\"image\"><a href=\"\' + item.path + \'\" rel=\"external nofollow\"  target=\"_blank\"><img class=\"img-responsive\" src=\"\' + item.path + \'\" ></a><div class=\"caption\"><p>\' + item.info + \'</p></div></div></div>\';
                        divs += div;
                    });
                    pic_body.innerHTML = divs;
 
 
                    // 加载页码导航
                    // previous
                    let previousBtn = \'\';
                    if (res.page_number == 1) {
                        previousBtn = \'<li class=\"page-item disabled\"><a class=\"page-link\" href=\"javascript:requestPage(\' + (res.page_number - 1) + \');\" rel=\"external nofollow\"  rel=\"external nofollow\" >Previous</a></li>\';
                    } else {
                        previousBtn = \'<li class=\"page-item\"><a class=\"page-link\" href=\"javascript:requestPage(\' + (res.page_number - 1) + \');\" rel=\"external nofollow\"  rel=\"external nofollow\" >Previous</a></li>\';
                    }
                    // next
                    let nextBtn = \'\';
                    if (res.page_total == res.page_number) {
                        nextBtn = \'<li class=\"page-item disabled\"><a class=\"page-link\" href=\"javascript:requestPage(\' + (res.page_number + 1) + \');\" rel=\"external nofollow\"  rel=\"external nofollow\" >Next</a></li>\';
                    } else {
                        nextBtn = \'<li class=\"page-item\"><a class=\"page-link\" href=\"javascript:requestPage(\' + (res.page_number + 1) + \');\" rel=\"external nofollow\"  rel=\"external nofollow\" >Next</a></li>\'
                    }
 
                    let pages = previousBtn;
                    for (let page = 1; page <= res.page_total; page++) {
                        let active = \'\';
                        if (page == res.page_number) {
                            active = \'active\';
                        }
                        pages += \'<li class=\"page-item \' + active + \'\"><a class=\"page-link\" href=\"javascript:requestPage(\' + page + \');\" rel=\"external nofollow\" >\' + page + \'</a></li>\';
                    }
                    pages += nextBtn;
                    pagination.innerHTML = pages;
                }   
            },\'json\');
        };
        requestData(1, \'\');
</script>
</body>
</html>

2.图片相关功能处理

upload_class.php

<?php
 
//接收传过来的数据
$description=$_POST[\'description\'];//描述
$mark=$_POST[\'mark\'];//水印
$scale=$_POST[\'scale\'];//比例 800*600
$path=\'\';//图片存储路径
 
 
//根据比例获取宽高
$width=substr($scale,0,3);//800
$height=substr($scale,4,3);//600
 
 
//上传图片并存储
require(\'UploadFile.php\');
 
$upload = new UploadFile(\'test_pic\');
$upload->setDestinationDir(\'./uploads\');
$upload->setAllowMime([\'image/jpeg\', \'image/gif\',\'image/png\']);
$upload->setAllowExt([\'gif\', \'jpeg\',\'jpg\',\'png\']);
$upload->setAllowSize(2*1024*1024);
if ($upload->upload()) {
    $filename=$upload->getFileName()[0];
    $dir=$upload->getDestinationDir();
    $path=$dir.\'/\'.$filename;//图片存储的实际路径
    
} else {
    var_dump($upload->getErrors());
}
 
 
//根据比例调整图像
require_once \'./lib/Image.php\';
$image = new \\test\\Lib\\Image($path);
//放大并保存
$image->resize($width,$height)->save($path);
 
$info = getimagesize($path);
//根据不同的图像type 来创建图像
switch($info[2])
{
    case 1://IMAGETYPE_GIF
        $image = imagecreatefromgif($path);
        break;
    case IMAGETYPE_JPEG:
        $image = imagecreatefromjpeg($path);
        break;
    case 3:
        $image = imagecreatefrompng($path);
        break;
 
    default:
        echo \'图像格式不支持\';
        break;
 
}
    
//添加水印
if($mark==1){
 
    $logo=imagecreatefrompng(\'./uploads/logo.png\');
    //添加水印
    imagecopy($image,$logo,0,0,0,0,imagesx($logo),imagesy($logo));
    //header(\'Content-type:image/png\');
    imagejpeg($image,$path);
}
 
$dst_image=imagecreatetruecolor($width,$height);
//拷贝源图像左上角起始
imagecopy( $dst_image, $image, 0, 0, 0, 0, $width, $height );
imagejpeg($dst_image,$path);
 
//存入数据库
$servername = \"localhost\";
$username = \"root\";
$password = \"123456\";
$dbname = \"pic\";
 
try {
$conn = new PDO(\"mysql:host=$servername;dbname=$dbname\", $username, $password);
// 设置 PDO 错误模式,用于抛出异常
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = \"INSERT INTO pic(`path`, `mark`, `scale`,`info`)
VALUES (\'$path\', \'$mark\', \'$scale\',\'$description\')\";
// 使用 exec() ,没有结果返回
$conn->exec($sql);
    exit(\"<script>alert(\\\"图片上传成功!\\\");window.location=\\\"index.php\\\";</script>\");
}
catch(PDOException $e)
{
    echo $sql . \"<br>\" . $e->getMessage();
}

3.封装好的文件上传类

UploadFile.php

<?php
/**
 * Created by PhpStorm.
 * User: JasonLee
 * Date: 2018/11/11
 * Time: 22:01
 */
 
class UploadFile
{
 
    /**
     *
     */
    const UPLOAD_ERROR = [
        UPLOAD_ERR_INI_SIZE => \'文件大小超出了php.ini当中的upload_max_filesize的值\',
        UPLOAD_ERR_FORM_SIZE => \'文件大小超出了MAX_FILE_SIZE的值\',
        UPLOAD_ERR_PARTIAL => \'文件只有部分被上传\',
        UPLOAD_ERR_NO_FILE => \'没有文件被上传\',
        UPLOAD_ERR_NO_TMP_DIR => \'找不到临时目录\',
        UPLOAD_ERR_CANT_WRITE => \'写入磁盘失败\',
        UPLOAD_ERR_EXTENSION => \'文件上传被扩展阻止\',
    ];
 
    /**
     * @var
     */
    protected $field_name;
 
    /**
     * @var string
     */
    protected $destination_dir;
 
    /**
     * @var array
     */
    protected $allow_mime;
 
    /**
     * @var array
     */
    protected $allow_ext;
 
    /**
     * @var
     */
    protected $file_org_name;
 
    /**
     * @var
     */
    protected $file_type;
 
    /**
     * @var
     */
    protected $file_tmp_name;
 
    /**
     * @var
     */
    protected $file_error;
 
    /**
     * @var
     */
    protected $file_size;
 
    /**
     * @var array
     */
    protected $errors;
 
    /**
     * @var
     */
    protected $extension;
 
    /**
     * @var
     */
    protected $file_new_name;
 
    /**
     * @var float|int
     */
    protected $allow_size;
 
    /**
     * UploadFile constructor.
     * @param $keyName
     * @param string $destinationDir
     * @param array $allowMime
     * @param array $allowExt
     * @param float|int $allowSize
     */
    public function __construct($keyName, $destinationDir = \'./uploads\', $allowMime = [\'image/jpeg\', \'image/gif\'], $allowExt = [\'gif\', \'jpeg\'], $allowSize = 2*1024*1024)
{
        $this->field_name = $keyName;
        $this->destination_dir = $destinationDir;
        $this->allow_mime = $allowMime;
        $this->allow_ext = $allowExt;
        $this->allow_size = $allowSize;
    }
 
    /**
     * @param $destinationDir
     */
    public function setDestinationDir($destinationDir)
{
        $this->destination_dir = $destinationDir;
    }
 
    /**
     * @param $allowMime
     */
    public function setAllowMime($allowMime)
{
        $this->allow_mime = $allowMime;
    }
 
    /**
     * @param $allowExt
     */
    public function setAllowExt($allowExt)
{
        $this->allow_ext = $allowExt;
    }
 
    /**
     * @param $allowSize
     */
    public function setAllowSize($allowSize)
{
        $this->allow_size = $allowSize;
    }
 
    /**
     * @return bool
     */
    public function upload()
{
        // 判断是否为多文件上传
        $files = [];
        if (is_array($_FILES[$this->field_name][\'name\'])) {
            foreach($_FILES[$this->field_name][\'name\'] as $k => $v) {
                $files[$k][\'name\'] = $v;
                $files[$k][\'type\'] = $_FILES[$this->field_name][\'type\'][$k];
                $files[$k][\'tmp_name\'] = $_FILES[$this->field_name][\'tmp_name\'][$k];
                $files[$k][\'error\'] = $_FILES[$this->field_name][\'error\'][$k];
                $files[$k][\'size\'] = $_FILES[$this->field_name][\'size\'][$k];
            }
        } else {
            $files[] = $_FILES[$this->field_name];
        }
 
        foreach($files as $key => $file) {
            // 接收$_FILES参数
            $this->setFileInfo($key, $file);
 
            // 检查错误
            $this->checkError($key);
 
            // 检查MIME类型
            $this->checkMime($key);
 
            // 检查扩展名
            $this->checkExt($key);
 
            // 检查文件大小
            $this->checkSize($key);
 
            // 生成新的文件名称
            $this->generateNewName($key);
 
            if (count((array)$this->getError($key)) > 0) {
                continue;
            }
            // 移动文件
            $this->moveFile($key);
        }
        if (count((array)$this->errors) > 0) {
            return false;
        }
        return true;
    }
 
    /**
     * @return array
     */
    public function getErrors()
{
        return $this->errors;
    }
 
    /**
     * @param $key
     * @return mixed
     */
    protected function getError($key)
{
        return $this->errors[$key];
    }
 
    /**
     *
     */
    protected function setFileInfo($key, $file)
{
        // $_FILES  name type temp_name error size
        $this->file_org_name[$key] = $file[\'name\'];
        $this->file_type[$key] = $file[\'type\'];
        $this->file_tmp_name[$key] = $file[\'tmp_name\'];
        $this->file_error[$key] = $file[\'error\'];
        $this->file_size[$key] = $file[\'size\'];
    }
 
 
    /**
     * @param $key
     * @param $error
     */
    protected function setError($key, $error)
{
        $this->errors[$key][] = $error;
    }
 
 
    /**
     * @param $key
     * @return bool
     */
    protected function checkError($key)
{
        if ($this->file_error > UPLOAD_ERR_OK) {
            switch($this->file_error) {
                case UPLOAD_ERR_INI_SIZE:
                case UPLOAD_ERR_FORM_SIZE:
                case UPLOAD_ERR_PARTIAL:
                case UPLOAD_ERR_NO_FILE:
                case UPLOAD_ERR_NO_TMP_DIR:
                case UPLOAD_ERR_CANT_WRITE:
                case UPLOAD_ERR_EXTENSION:
                    $this->setError($key, self::UPLOAD_ERROR[$this->file_error]);
                    return false;
            }
        }
        return true;
    }
 
 
    /**
     * @param $key
     * @return bool
     */
    protected function checkMime($key)
{
        if (!in_array($this->file_type[$key], $this->allow_mime)) {
            $this->setError($key, \'文件类型\' . $this->file_type[$key] . \'不被允许!\');
            return false;
        }
        return true;
    }
 
 
    /**
     * @param $key
     * @return bool
     */
    protected function checkExt($key)
{
        $this->extension[$key] = pathinfo($this->file_org_name[$key], PATHINFO_EXTENSION);
        if (!in_array($this->extension[$key], $this->allow_ext)) {
            $this->setError($key, \'文件扩展名\' . $this->extension[$key] . \'不被允许!\');
            return false;
        }
        return true;
    }
 
    /**
     * @return bool
     */
    protected function checkSize($key)
{
        if ($this->file_size[$key] > $this->allow_size) {
            $this->setError($key, \'文件大小\' . $this->file_size[$key] . \'超出了限定大小\' . $this->allow_size);
            return false;
        }
        return true;
    }
 
 
    /**
     * @param $key
     */
    protected function generateNewName($key)
{
        $this->file_new_name[$key] = uniqid() . \'.\' . $this->extension[$key];
    }
 
 
    /**
     * @param $key
     * @return bool
     */
    protected function moveFile($key)
{
        if (!file_exists($this->destination_dir)) {
            mkdir($this->destination_dir, 0777, true);
        }
        $newName = rtrim($this->destination_dir, \'/\') . \'/\' . $this->file_new_name[$key];
        if (is_uploaded_file($this->file_tmp_name[$key]) && move_uploaded_file($this->file_tmp_name[$key], $newName)) {
            return true;
        }
        $this->setError($key, \'上传失败!\');
        return false;
    }
 
    /**
     * @return mixed
     */
    public function getFileName()
{
        return $this->file_new_name;
    }
 
    /**
     * @return string
     */
    public function getDestinationDir()
{
        return $this->destination_dir;
    }
 
    /**
     * @return mixed
     */
    public function getExtension()
{
        return $this->extension;
    }
 
    /**
     * @return mixed
     */
    public function getFileSize()
{
        return $this->file_size;
    }
 
}

4.搜索功能实现

search.php

<?php
 
// 接收请求数据
$pageNo = $_GET[\'page\'] ?? 1;
$pageSize = 9;
 
// 接收查询参数
$keywords = $_GET[\'keywords\'] ?? \'\';
 
$data = [];
//模拟加载中的图标sleep(3);
try {
    $pdo = new PDO(\'mysql:host=localhost:3306;dbname=pic\',
        \'root\',
        \'123456\',
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );
 
    // 请求mysql 查询记录总数
    $sql = \'SELECT count(*) AS aggregate FROM pic\';
    if (strlen($keywords) > 0) {
        $sql .= \' WHERE info like ?\';
    }
    $stmt = $pdo->prepare($sql);
    if (strlen($keywords) > 0) {
        $stmt->bindValue(1, \'%\' . $keywords . \'%\', PDO::PARAM_STR);
    }
    $stmt->execute();
    $total = $stmt->fetch(PDO::FETCH_ASSOC)[\'aggregate\'];
    
    // 计算最大页码,设置页码边界
    $minPage = 1;
    $maxPage = ceil($total / $pageSize); // 3.6
    $pageNo = max($pageNo, $minPage);
    $pageNo = min($pageNo, $maxPage);
    $offset = ($pageNo - 1) * $pageSize;
 
 
    $sql=\"SELECT `path`,`info` FROM pic \";
    if (strlen($keywords) > 0) {
        $sql .= \' WHERE info like ?\';
    }
    $sql .= \'ORDER BY id DESC LIMIT ?, ?\';
    $stmt = $pdo->prepare($sql);
    if (strlen($keywords) > 0) {
        $stmt->bindValue(1, \'%\' . $keywords . \'%\', PDO::PARAM_STR);
        $stmt->bindValue(2, (int)$offset, PDO::PARAM_INT);
        $stmt->bindValue(3, (int)$pageSize, PDO::PARAM_INT);
    } else {
        $stmt->bindValue(1, (int)$offset, PDO::PARAM_INT);
        $stmt->bindValue(2, (int)$pageSize, PDO::PARAM_INT);
    }
    $stmt->execute();
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $data = [
        \'code\' => 1,
        \'msg\' => \'ok\',
        \'rows\' => $results,
        \'total_records\' => (int)$total,
        \'page_number\' => (int)$pageNo,
        \'page_size\' => (int)$pageSize,
        \'page_total\' => (int)$maxPage,
    ];   
 
} catch (PDOException $e) {
    $data = [
        \'code\' => 0,
        \'msg\' => $e->getMessage(),
        \'rows\' => [],
        \'total_records\' => 0,
        \'page_number\' => 0,
        \'page_size\' => (int)$pageSize,
        \'page_total\' => 0,
    ];
}
 
header(\'Content-type: application/json\');
echo json_encode($data);

4.最后数据库格式 

/*
Navicat MySQL Data Transfer

Source Server         : localhost
Source Server Version : 80012
Source Host           : localhost:3306
Source Database       : pic

Target Server Type    : MYSQL
Target Server Version : 80012
File Encoding         : 65001

Date: 2020-01-14 16:22:49
*/
 
SET FOREIGN_KEY_CHECKS=0;
 
-- ----------------------------
-- Table structure for pic
-- ----------------------------
DROP TABLE IF EXISTS `pic`;
CREATE TABLE `pic` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `path` varchar(255) DEFAULT NULL,
  `mark` tinyint(3) DEFAULT NULL,
  `scale` varchar(255) DEFAULT NULL,
  `info` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Records of pic
-- ----------------------------
INSERT INTO `pic` VALUES (\'1\', \'./uploads/5e1d788084cc5.jpg\', \'1\', \'800*600\', \'这是测试图片1\');
INSERT INTO `pic` VALUES (\'2\', \'./uploads/5e1d789766591.jpg\', \'1\',

以上就是PHP实现文件上传和下载的示例代码的详细内容,更多关于PHP文件上传下载的资料请关注其它相关文章!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容