本文為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></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-view7.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);
}
}
});
});
}