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服务启动,脚本路径写绝对路径

更多推荐