thinkphp阿里云服务器ecs上传图片
ThinkPHP + 阿里云ECS 自动化上传图片完整方案
分两种主流方案:
1. 本地上传至ECS服务器本地目录(简单,适合中小型项目)
2. 直传阿里云OSS对象存储(推荐,自动化、高并发、无需占用ECS磁盘)
前置准备
1. ECS环境依赖
1. PHP开启GD库(缩放、水印)
2. 安装图像处理扩展
bash
composer require topthink/think-image
3. ECS安全组放行端口:80/443,文件上传无限制;
4. 项目目录赋予读写权限:
bash
chmod -R 755 /www/wwwroot/你的项目目录
chown -R www:www /www/wwwroot/你的项目目录
方案一:图片自动上传存储到ECS本地磁盘
1. 配置 filesystem.php(TP6)
php
'disks' => [
'local' => [
'type' => 'local',
'root' => app()->getRuntimePath() . 'storage',
],
'public' => [
'type' => 'local',
'root' => public_path() . 'uploads', // 直接存在public/uploads
'url' => '/uploads',
'visibility' => 'public',
],
],
2. 自动化上传+等比例缩放+水印控制器
php
<?php
namespace app\controller;
use think\Request;
use think\Image;
use think\facade\Filesystem;
class Upload
{
public function image(Request $request)
{
$file = $request->file('file');
if (!$file) return json(['code' => 0, 'msg' => '未选择图片']);
// 上传校验
$file->validate([
'size' => 5 * 1024 * 1024,
'ext' => 'jpg,jpeg,png,gif,webp'
]);
if ($file->getError()) {
return json(['code' => 0, 'msg' => $file->getError()]);
}
// 自动生成日期目录保存文件
$savePath = Filesystem::disk('public')->putFile(date('Ym/d'), $file);
$imgUrl = '/uploads/' . $savePath;
$fullPath = public_path('uploads/' . $savePath);
try {
$image = Image::open($fullPath);
$maxW = 1000;
$maxH = 1000;
// 等比例缩放
if ($image->width() > $maxW || $image->height() > $maxH) {
$image->thumb($maxW, $maxH, Image::THUMB_SCALING);
}
// 加水印
$waterFile = public_path('water.png');
if (file_exists($waterFile)) {
$image->water($waterFile, Image::WATER_SOUTHEAST, 70);
}
$image->save($fullPath);
return json([
'code' => 1,
'msg' => '上传成功',
'data' => [
'src' => $imgUrl,
'path' => $fullPath
]
]);
} catch (\Exception $e) {
unlink($fullPath);
return json(['code' => 0, 'msg' => '图片处理失败:' . $e->getMessage()]);
}
}
}
3. 自动化定时清理(ECS磁盘避免爆满)
ECS磁盘有限,写定时任务自动删除30天前无用图片
Linux crontab 定时脚本 clean_img.sh
sh
#!/bin/bash
find /www/wwwroot/项目目录/public/uploads -mtime +30 -delete
赋予执行权限:
bash
chmod +x clean_img.sh
添加定时任务,每天凌晨1点执行:
bash
crontab -e
0 1 * * * /www/wwwroot/clean_img.sh
方案二:自动化上传阿里云OSS(推荐,企业级)
图片不占ECS硬盘、CDN加速、自动归档,扩容无压力
1. 安装阿里云OSS扩展
bash
composer require aliyun/oss-sdk-php
2. 配置 config/oss.php
php
return [
'access_key_id' => '你的AccessKeyID',
'access_key_secret' => '你的AccessKeySecret',
'endpoint' => 'oss-cn-xxx.aliyuncs.com',
'bucket' => '你的bucket名称',
'cdn_domain' => 'https://图片加速域名', // 可选CDN
];
3. OSS上传控制器(本地缩放水印后自动推送到OSS)
流程:前端上传到ECS临时目录 → 压缩+水印 → 自动上传OSS → 删除本地临时文件
php
<?php
namespace app\controller;
use think\Request;
use think\Image;
use OSS\OssClient;
use OSS\Core\OssException;
class OssUpload
{
public function img(Request $request)
{
$file = $request->file('file');
if (!$file) return json(['code' => 0, 'msg' => '无文件']);
$validate = ['size' => 5242880, 'ext' => 'jpg,jpeg,png,gif,webp'];
$file->validate($validate);
if ($file->getError()) return json(['code' => 0, 'msg' => $file->getError()]);
// 临时保存到ECS本地
$tempPath = $file->getRealPath();
$saveName = date('Ym/d') . '/' . md5_file($tempPath) . '.' . $file->getExtension();
try {
// 图片缩放水印处理
$image = Image::open($tempPath);
if ($image->width() > 1000 || $image->height() > 1000) {
$image->thumb(1000, 1000, Image::THUMB_SCALING);
}
$water = public_path('water.png');
if (file_exists($water)) {
$image->water($water, Image::WATER_SOUTHEAST, 70);
}
// 生成临时处理文件
$processTemp = runtime_path() . uniqid() . '.' . $file->getExtension();
$image->save($processTemp);
// 初始化OSS
$ossConfig = config('oss');
$ossClient = new OssClient(
$ossConfig['access_key_id'],
$ossConfig['access_key_secret'],
$ossConfig['endpoint']
);
// 自动上传到OSS
$ossClient->uploadFile($ossConfig['bucket'], $saveName, $processTemp);
// 清理ECS本地临时文件
unlink($tempPath);
unlink($processTemp);
$imgUrl = !empty($ossConfig['cdn_domain'])
? $ossConfig['cdn_domain'] . '/' . $saveName
: 'https://' . $ossConfig['bucket'] . '.' . $ossConfig['endpoint'] . '/' . $saveName;
return json([
'code' => 1,
'msg' => '上传OSS成功',
'data' => ['src' => $imgUrl]
]);
} catch (OssException $e) {
return json(['code' => 0, 'msg' => 'OSS上传失败:' . $e->getMessage()]);
} catch (\Exception $e) {
return json(['code' => 0, 'msg' => '图片处理异常:' . $e->getMessage()]);
}
}
}
三、全自动运维配套方案(ECS)
1. 自动备份图片(本地存储方案)
定时将uploads目录打包上传阿里云OSS备份
crontab定时脚本 backup_img.sh
sh
#!/bin/bash
DATE=$(date +%Y%m%d)
tar -zcvf /data/backup/img_$DATE.tar.gz /www/wwwroot/项目/public/uploads
# 上传备份包到OSS
ossutil cp /data/backup/img_$DATE.tar.gz oss://bucket/backup/
2. 前端通用上传JS(兼容ECS本地/OSS接口)
html
<input type="file" id="uploadImg" accept="image/*">
<script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script>
<script>
$('#uploadImg').on('change', function () {
let file = this.files[0];
if (!file) return;
let formData = new FormData();
formData.append('file', file);
$.ajax({
url: "{:url('Upload/image')}", // 切换OssUpload/img即为OSS上传
type: 'POST',
data: formData,
contentType: false,
processData: false,
success: res => {
if (res.code === 1) {
console.log('图片地址', res.data.src);
} else {
alert(res.msg);
}
}
})
})
</script>
四、两种方案优缺点对比
方案1 ECS本地存储
- 优点:简单、无OSS费用、上手快
- 缺点:占用ECS磁盘,图片多会爆满;扩容麻烦;无CDN访问慢;服务器重装图片丢失
方案2 阿里云OSS自动化上传(推荐)
- 优点:不占用ECS硬盘、CDN加速、无限扩容、OSS自动备份、服务器迁移图片不受影响
- 缺点:少量存储流量费用,多一层OSS配置
五、常见踩坑(阿里云ECS专属)
1. 上传报错权限不足
/www 目录权限改为 www 用户组运行
2. OSS内网访问提速
endpoint 使用内网地址 oss-cn-xxx-internal.aliyuncs.com,ECS同区域免流量费
3. 图片跨域访问
OSS后台设置跨域规则,允许前端域名访问图片
4. 大图片处理内存溢出
php.ini 调整 memory_limit=256M
5. 定时任务不执行
确认crontab服务启动,脚本路径写绝对路径
更多推荐
所有评论(0)