• Light App Engine 重构仍在进行中,但是目前我们正在举行活动,点击这里查看。

PHP文件上传功能完全实现(6次安全验证)- 来自山河

shanhe

山河
管理成员
2020-02-26
65
31
18
23
中国
blog.shanhe.info
hello,时隔多天,回来发帖子了,我是山河,这次我发的帖子是
PHP文件/图片单次上传功能的实现
写了普通的基本安全验证,代码简单,代码每一处地方都写了注释,简单易懂


本文转自我博客,文章本人原创

话不多说,上代码

PS:本人技术简陋,如果有安全漏洞欢迎指点,谢谢。
PHP:
<?php

// 设置编码
header('Content-type:text/html;charset=utf-8');

// PHP文件上传功能封装函数
// 图片
/*
is_array() 函数用于检测变量是否是一个数组
isset() 函数用于检测变量是否已设置并且非 NULL。
is_dir() 函数检查指定的文件是否是目录。
in_array() 函数搜索数组中是否存在指定的值。
*/


//山河

function upload_single($file,$allow_type,$path,&$error,$allow_format = array(),$max_size = 2000000) {
    // 判断文件是否有效
    if(!is_array($file) || !isset($file['error'])) {
        // 文件无效
        $error = '不是一个有效的上传文件!';
        return false;
    }

    // 判断文件存储路径是否有效
    if(!is_dir($path)) {
        // 路径不存在
        $error = '文件存储路径不存在!';
        return false;
    }

    // 判断文件上传是否出错
    switch($file['error']) {
        case 1:
        case 2:
            $error = '文件超出服务器允许大小';
            return false;
        case 3:
            $error = '文件上传过程中出现问题,只上传一部分!';
            return false;
        case 4:
            $error = '用户没有选中要上传的文件!';
        case 6:
        case 7:
            $error = '文件保存失败!';
            return false;
    }

    //判断MIME 类型
    if(!in_array($file['type'],$allow_type)) {
        // 该文件不允许上传
        $error = "该文件类型不允许上传!";
        return false;
    }

    // 判断后缀是否允许
    // 取出后缀
    $ext = ltrim(strrchr($file['name'],'.'),'.');
    // 不为空且不为允许的后缀
    if(!empty($allow_format) && !in_array($ext,$allow_format)) {
        // 不允许上传
        $error = '当前文件的格式不允许上传!';
        return false;
    }

    // 判断当前文件大小是否满足当前需求
    if($file['size'] > $max_size) {
        // 文件过大
        $error = '当前上传的文件超出大小,最大允许:' . $max_size/1000 . 'kb!';
        return false;
    }

    // 构造文件名字:类型_年月日_随机字符串.$ext
    $fullname = strstr($file['type'],'/',TRUE) . date('YYYYmmdd');
    // 产生随机字符串
    for($i = 0;$i < 4;$i++) {
        $fullname .= chr(mt_rand(65,90));
    }
    // 拼凑后缀
    $fullname .= '.' . $ext;

    // 移动到指定目录
    if(!is_uploaded_file($file['tmp_name'])) {
        // 文件不是上传的
        $error = '错误:不是上传文件 !';
        return false;
    }

    if(move_uploaded_file($file['tmp_name'],$path . '/' . $fullname)) {
        // 成功
        return '托管后的文件路径' . $fullname;
    } else {
        // 移动失败
        $error = '文件上传失败 !';
        return false;
    }


}

// 提供数据
// 获取数据
$file = $_FILES['image'];
// 保存的路径
$path = 'demo-8-functions/';
// mime允许上传的类型
$allow_type = array(
    'image/gif',
    'image/jpeg',
    'image/bmp',
    'image/png',
    'image/pjpeg'
);
// 允许上传的后缀
$allow_format = array(
    'jpg',
    'jpeg',
    'gif',
    'png',
    'bmp',
    'pjpeg',
    'jpe'
);
// 允许上传的文件最大值
$max_size = 8000000;




if($filename = upload_single($file,$allow_type,$path,$error,$allow_format,$max_size)) {
    echo $filename;
} else {
    echo $error;
}

?>
感谢你浏览本文章 by.山河/shanhe
原文链接:山河-PHP文件上传功能实现 – 山河技术分享 (blog.shanhe.info)