封裝ThinkPHP6.0通用文件上傳

2021-02-20 php中文網最新課程

本文為php中文網認證作者:「wpj」投稿,歡迎加入php中文網有償投稿計劃!

本文實例講述了封裝ThinkPHP6通用文件上傳方法,上傳功能使用的是LayUI的upload組件。

封裝ThinkPHP6.0通用文件上傳教程

一、打開項目在config文件夾下創建upload.php配置文件用來管理文件上傳的後綴和大小

<?php
return [
//定義允許上傳文件後綴的數組
'suffix_arr' => [
//允許圖片上傳的後綴
'image' => 'jpg,jpeg,png,gif',
//允許上傳文件的後綴
'file' => 'zip,gz,doc,txt,pdf,xls',
//...
],
//定義允許上傳文件大小的數組
'size_arr' => [
//允許圖片上傳的大小
'image' => 10,
//允許文件上傳的大小
'file' => 50
],
];

二、修改config\filesystem.php配置文件配置上傳根目錄及上傳規則

<?php
return [
// 默認磁碟
'default' => env('filesystem.driver', 'local'),
// 磁碟列表
'disks' => [
'local' => [
'type' => 'local',
'root' => app()->getRuntimePath() . 'storage',
],
'public' => [
// 磁碟類型
'type' => 'local',
// 磁碟路徑
'root' => app()->getRootPath() . 'public/uploads',
// 磁碟路徑對應的外部URL路徑
'url' => '/uploads',
// 可見性
'visibility' => 'public',
],
// 更多的磁碟配置信息
],
];

三、 在app\controller目錄下創建Upload.php類並編寫upload()文件上傳方法

<?php
namespace app\controller;
use think\exception\ValidateException;
class Upload{
//上傳
public function upload(){
//判斷是否是POST請求,如果是處理上傳邏輯
if (request()->isPost()){
//接收文件上傳類型
$type = request()->param('type','','trim');
$name = request()->param('name','','trim');
//獲取表單上傳文件
$file = request()->file('file');
//組裝文件保存目錄
$upload_dir = '/'.$type.'/'.$name;
try {
//從config/upload.php配置文件中讀取允許上傳的文件後綴和大小
$suffix_config = config('upload.suffix_arr');
$size_config = config('upload.size_arr');
if (empty($size_config[$type]) || empty($size_config[$type])){
return false;
}else{
$suffix = $suffix_config[$type];
$size = $size_config[$type];
}
//驗證器驗證上傳的文件
validate(['file'=>[
//限制文件大小
'fileSize' => $size * 1024 * 1024,
//限制文件後綴
'fileExt' => $suffix
]],[
'file.fileSize' => '上傳的文件大小不能超過'.$size.'M',
'file.fileExt' => '請上傳後綴為:'.$suffix.'的文件'
])->check(['file'=>$file]);
//上傳文件到本地伺服器
$filename = \think\facade\Filesystem::disk('public')->putFile($upload_dir, $file);
if ($filename){
$src = '/uploads/'.$filename;
return json(['code'=>1,'result'=>$src]);
}else{
return json(['code'=>0,'msg'=>'上傳失敗']);
}
}catch (ValidateException $e){
return json(['code'=>0,'msg'=>$e->getMessage()]);
}
}else{
return json(['code'=>0,'msg'=>'非法請求']);
}
}
}

四、 打開app\controller\Index.php類並修改index方法

<?php
namespace app\controller;
use app\BaseController;
class Index extends BaseController{
public function index(){
//渲染前端頁面
return view();
}
}

五、在app\view\index目錄下創建index.html文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上傳</title>
<!-- layui.css 推薦使用本地文件 -->
<link rel="stylesheet" href="https://heerey525.github.io/layui-v2.4.3/layui-v2.4.4/css/layui.css" media="all">
<style>
#avatar_thumb {
position: absolute;
left: 50%;top: 50%;
width: 168px;
height: 168px;
margin: -50px 0 0 -84px;
border-radius: 100%;
}</style>
</head>
<body>


<div style="text-align: center;">
<div>
<div style="position: relative;width: 373px;height: 373px;background-color: #F2F2F5;margin: auto;">
<button type="button" id="avatar">
<i>&#xe67c;</i>上傳頭像
</button>
<img src="" id="avatar_thumb">
<input type="hidden" name="avatar" value="">
</div>
</div>
</div>


<!-- layui.js 和jquery.js 推薦使用本地文件 -->
<script src="https://heerey525.github.io/layui-v2.4.3/layui-v2.4.4/layui.js" charset="utf-8"></script>
<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
<script src="/static/lib/js/common.js"></script>
<script>
layui.use(['form', 'upload'], function() {
var upload = layui.upload;


//圖片上傳
common_upload('avatar');


//文件上傳
//common_upload('avatar','file');
});</script>
</body>
</html>

六、在public\static\lib\js目錄下創建common.js

/**
* @desc 通用文件上傳
* @param name 文件存儲文件夾
* @param type 文件類型:默認為圖片類型(image)
*/
function common_upload(name,type='image') {


layui.use(['form', 'upload'], function() {
var upload = layui.upload;


//選完文件後自動上傳
upload.render({
elem: '#'+name,
url: "/upload/upload",
auto: true,
accept: 'file', //普通文件
data:{name:name,type:type},


done: function(data) {
console.log(data);
//上傳完畢回調
if (data.code == 0) {
return layer.msg(data.msg,{icon:2});
} else {
$("#"+name+"_thumb").attr('src',data.result).show();
$('input[name='+name+']').val(data.result);
}
}
});
});
}

七、測試圖片上傳

7.1、為了方便,本文就不在本地部署項目了,採用ThinkPHP內置的伺服器

進到項目根目錄,執行以下命令:

7.2、在瀏覽器地址欄中輸入訪問地址,發現報錯?

7.3、遇到錯誤不要慌,我們打開ThinkPHP的調試功能,看看具體錯誤信息

7.4、通過開啟調試模式,發現報錯原因是我們沒有安裝模板引擎,在ThinkPHP6.0中默認只能支持PHP原生模板,如果需要使用thinkTemplate模板引擎,需要安裝think-view擴展

7.5、進到項目根目錄下,輸入以下命令進行安裝think-view模板

composer require topthink/think-view

7.6、再次訪問,訪問成功。不過圖片顯示的是破裂的,如果覺得不好看,小夥伴們可以自行設置一個默認圖片。

7.7、測試圖片上傳。從GIF圖中可以看出上傳圖片大小和後綴不符合配置文件中設置的值,會給出相應的提示信息,只有上傳符合配置文件中設置的值的圖片才會在頁面中顯示並存儲到本地。

7.8、如果需要上傳文件,視頻或音頻,只需要修改以下兩個地方,這裡就不演示了,小夥伴們下去自己試下。

八、新圖片上傳成功後自動刪除原圖,有效地減少垃圾信息的累積

8.1、在app\controller\Upload.php中添加delImg() 方法

<?php

namespace app\controller;

use think\exception\ValidateException;

class Upload{

public function upload(){

if (request()->isPost()){


$type = request()->param('type','','trim');
$name = request()->param('name','','trim');

$file = request()->file('file');

$upload_dir = '/'.$type.'/'.$name;

try {

$suffix_config = config('upload.suffix_arr');
$size_config = config('upload.size_arr');

if (empty($size_config[$type]) || empty($size_config[$type])){
return false;
}else{
$suffix = $suffix_config[$type];
$size = $size_config[$type];
}

validate(['file'=>[

'fileSize' => $size * 1024 * 1024,

'fileExt' => $suffix
]],[
'file.fileSize' => '上傳的文件大小不能超過'.$size.'M',
'file.fileExt' => '請上傳後綴為:'.$suffix.'的文件'
])->check(['file'=>$file]);


$filename = \think\facade\Filesystem::disk('public')->putFile($upload_dir, $file);
if ($filename){
$src = '/uploads/'.$filename;
return json(['code'=>1,'result'=>$src]);
}else{
return json(['code'=>0,'msg'=>'上傳失敗']);
}
}catch (ValidateException $e){
return json(['code'=>0,'msg'=>$e->getMessage()]);
}
}else{
return json(['code'=>0,'msg'=>'非法請求']);
}
}


public function delImg(){
if (request()->isPost() && request()->isAjax()){

$img_url = input('img_url','','trim');

if($img_url == '/uploads/image/avatar/default/user_avatar.jpg'){
return true;
}

define('ROOT_PATH',dirname(str_replace("\\",'/',$_SERVER['SCRIPT_FILENAME']))."/");

if (!empty($img_url)){
$old_image = array(ROOT_PATH.$img_url);
foreach ($old_image as $img){
if (file_exists($img)){
@unlink($img);
}
}
}
return json(['code'=>1,'msg'=>'圖片刪除成功']);
}else{
return json(['code'=>0,'msg'=>'圖片刪除失敗']);
}
}
}

8.2、在common.js中的common_upload()方法中定義before()






function common_upload(name,type='image') {

layui.use(['form', 'upload'], function() {
var upload = layui.upload;


upload.render({
elem: '#'+name,
url: "/upload/upload",
auto: true,
accept: 'file',
data:{name:name,type:type},

before: function(obj) {
var img_url = $('input[name='+name+']').val();

if (img_url != '') {
$.ajax({
url: "/upload/delImg",
type: 'POST',
data: {
img_url: img_url
},
});
}
},

done: function(data) {
console.log(data);

if (data.code == 0) {
return layer.msg(data.msg,{icon:2});
} else {
$("#"+name+"_thumb").attr('src',data.result).show();
$('input[name='+name+']').val(data.result);
}
}
});
});
}

相關焦點

  • ThinkPHP6.0開啟多應用模式
    1、安裝thinkphp6.0框架:composer create-project topthink/think thinkphpV6.0.5生成目錄,默認安裝後的目錄結構就是一個單應用模式。:注意:BaseController.php、Request.php 和ExceptionHandle.php三個文件是系統默認提供的基礎文件,位置你可以隨意移動,但注意要同步調整類的命名空間。
  • ThinkPHP6.0任意文件創建Getshell復現
    該漏洞源於ThinkPHP 6.0的某個邏輯漏洞,成功利用此漏洞的攻擊者可以實現「任意」文件創建,在特殊場景下可能會導致GetShell。2020年1月10日,ThinkPHP團隊發布一個補丁更新,修復了一處由不安全的SessionId導致的任意文件操作漏洞。該漏洞允許攻擊者在目標環境啟用session的條件下創建任意文件以及刪除任意文件,在特定情況下還可以getshell。
  • 【技術分享】通過thinkphp開發學習,理解漏洞產生原理
    https://www.kancloud.cn/manual/thinkphp5_1/353946有文件後綴驗證的例子在普通上傳文件例子,多文件上傳例子的後面。新建一個Base的類,在初始化的initialize進行session或者登陸的判斷,然後其他控制器類繼承Base類,那麼整個類的方法就都有權限驗證了。
  • 文件上傳雜談
    本文將針對文件上傳的一些通用維度場景做簡單的剖析和嘗試,拋磚引玉,希望共同學習,共同成長。本文案例裡使用的組件來源於組件庫 zent@7.4.4二、常見的上傳場景及實現上傳的形式或場景各式各樣,除了業務級別的封裝外,常遇到的通用場景有如下:重複上傳上傳預覽拖拽上傳上傳裁剪上傳進度可視化文件壓縮上傳前置校驗切片上傳上傳加密暫停&斷網續傳 ...
  • Thinkphp製作404跳轉頁
    本篇文章介紹了使用ThinkPHP實現404頁面的方法,希望對學習thinkphp的朋友有幫助!
  • SpringMVC文件上傳下載
    SpringMVC文件上傳文件上傳和下載是web開發常用模塊,而SpringMVC作為一款優秀的web框架,對很多模塊和內容進行更高度的封裝和集成,而這麼常用的文件上傳肯定是少不了的,所以SpringMVC的文件上傳基於apache旗下開源的commons-fileupload和 commons-io包。
  • 一篇講文件上傳的
    0x01 前言文件上傳算是比較常見的getshell的方式了,但是總會遇到一些網站源碼中編寫的規則啊,或者一些安全設備等對上傳的惡意文件進行攔截,這時候我們就要去了解相關產品檢測我們惡意文件的方法,進而找到產品的不足之處,對產品進行繞過從而成功getshell。
  • PHP上傳文件和下載
    >在 B/S 程序中文件上傳已經成為一個常用功能。1.2 在伺服器端通過 PHP 處理上傳上傳文件的接收和處理是通過 PHP 腳本來處理的,具體需要通過以下三個方面信息:1)設置 PH 配置文件中的指令:用於精細地調節 PHP 的文件上傳功能。2)$FILES 多維數組:用於存儲各種與上傳文件有關的信息,其他數據還是使用 $_POST 獲取。
  • Spring Boot + Vue 前後端分離,兩種文件上傳方式總結!
    Ajax 上傳在 Vue 中,通過 Ajax 實現文件上傳,方案和傳統 Ajax 實現文件上傳基本上是一致的,唯一不同的是查找元素的方式。這種文件上傳方式,實際上就是傳統的 Ajax 上傳文件,和大家常見的 jQuery 中寫法不同的是,這裡元素查找的方式不一樣(實際上元素查找也可以按照JavaScript 中原本的寫法來實現),其他寫法一模一樣。這種方式是一個通用的方式,和使用哪一種前端框架無關。
  • 原創 | 淺談Springboot中的文件上傳
    在JavaWeb應用中,任意文件上傳一直是關注的重點,攻擊者通過上傳惡意jsp文件,可以獲取伺服器權限。
  • 拆解 UI 組件 el-upload 文件上傳
    el-upload 主要由 3 塊組成:第一部分:文件選擇文件選擇部分是通過對 input 標籤進行封裝,可以看下源碼:<input  type="file"  ref="input"  name={name}  on-change={handleChange
  • OkHttp封裝
    在真實的企業開發中,肯定是把這些代碼封裝起來,做一個庫,給Activity調用。封裝之前我們需要考慮以下這些問題:封裝基本的公共方法給外部調用。get請求,Post請求,PostFile官方建議OkHttpClient實例只new一次,那我們網絡請求庫可以做成單例模式。
  • java web文件上傳與下載
    引言在Web應用中,由於大多數文件的上傳都是通過表單的形式提交給伺服器的,因此,要想在程序中實現文件上傳的功能,首先得創建一個用於提交上傳文件的表單頁面
  • thinkphp - 遠程執行漏洞的本地復現
    0x01 漏洞簡介由於ThinkPHP5 框架控制器名 沒有進行足夠的安全監測,導致在沒有開啟強制路由的情況下,可以偽裝特定的請求可以直接Getshell(可以控制伺服器)0x02 環境搭建Phpstudy:php-5.5.38 Apache下載存在漏洞版本我下載的版本是thinkphp
  • cmd上傳文件的N種方法
    0x00 前言在滲透測試的過程中,常常需要向目標主機上傳文件。所以本文就對該技巧做一下總結。0x02 測試環境 OS:Win7 x860x03 通用上傳方法17、bitsadminbitsadmin是一個命令行工具,可用於創建下載或上傳工作和監測其進展情況。
  • 通達OA文件上傳文件包含漏洞分析
    本次復現環境是通達OAV11.3,文件上傳漏洞為全版本通殺,文件包含漏洞/ispirit/interface/gateway.php只有V11.3版本存在。_("接收方ID無效")); echo json_encode(data2utf8($dataBack)); exit(); }}傳入一個DEST_UID=2後,訪問,提示無文件上傳,進入文件上傳邏輯。
  • TDH 6.0新版本功能大解析(上)
    Manager:Manager開始獨立於TDH,成為通用服務,為更多產品線(如KunDB、ArgoDB等)提供在線部署升級管理以及全線性的運維支撐。Search:Search作為支持SQL的搜尋引擎,在新版本中增強了存儲效率和穩定性,並深化了SQL語句的支持度和優化能力。
  • 【JavaWeb基礎】文件上傳和下載(修訂版)
    文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3y什麼是文件上傳?文件上傳就是把用戶的信息保存起來。為什麼需要文件上傳?在用戶註冊的時候,可能需要用戶提交照片。那麼這張照片就應該要進行保存。上傳組件(工具)為什麼我們要使用上傳工具?為啥我們需要上傳組件呢?
  • 【第1537期】Fusion Next 之 Upload 上傳組件設計思路
    文件上傳完後頁面會刷新帶來的體驗問題原生的文件上傳都是通過form post 上傳,上傳完成後整個頁面會重定向到 action 的地址。現在大家已經習慣了 ajax 做數據提交,因為可以不需要reload頁面就可以帶來整個頁面的數據更新,無刷新更新的體驗會提升很多。
  • 用 Power Apps 製作上傳門戶應用 - 上傳文件至Azure stroage(下)
    上一期我們介紹了用power apps製作門戶上傳應用的三個步驟,分別是:創建Blob container、在Power Apps中建立Blob接口和創建畫布應用。本期我們將介紹第四個步驟——構建應用邏輯。