安装阿里云 OSS SDK
在网站根目录下执行以下 Composer 命令,安装阿里云 OSS 官方 SDK:
composer require aliyuncs/oss-sdk-php
安装完成后,会在网站根目录的 vendor 文件夹下生成 aliyuncs 目录,包含 SDK 核心文件。
获取 OSS 访问凭证
1. 必备参数说明
上传文件前需准备以下 4 个核心参数,可在阿里云 OSS 控制台获取:
-
Endpoint:OSS 地域节点(如香港节点
oss-cn-hongkong.aliyuncs.com) -
AccessKeyId:访问密钥 ID
-
AccessKeySecret:访问密钥密钥
-
Bucket:存储空间名称(需提前在 OSS 控制台创建)
2. 参数获取路径
登录 阿里云 OSS 控制台 → 进入目标存储空间 → 查看「概览」获取 Endpoint 和 Bucket 名称;访问 AccessKey 管理控制台 生成/查看 AccessKeyId 和 AccessKeySecret。
完整实现代码
1. 前端上传页面(upload.html)
提供文件选择和提交功能,支持 multipart/form-data 格式上传:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>OSS 图片上传示例</title>
</head>
<body>
<form action="oss-image/upload-image.json" method="post" enctype="multipart/form-data">
<label for="file">选择文件:</label>
<input type="file" name="image" id="file" accept="image/*"><br>
<input type="submit" name="submit" value="上传文件">
</form>
</body>
</html>
注:accept="image/*" 限制仅上传图片文件,可根据需求删除该属性支持所有文件类型。
2. 控制器(OssImageController.php)
接收前端请求,转发至 Service 层处理(控制层与业务层分离):
<?php
declare(strict_types = 1);
namespace app\controllers;
use app\services\OssImageService;
use yii\web\Controller;
class OssImageController extends Controller
{
/**
* OSS 文件上传接口
* @return array 上传结果(含文件URL)
* @throws \OSS\Core\OssException
*/
public function actionUploadImage()
{
// 直接调用 Service 层上传逻辑,返回标准化响应
return $this->asJson(OssImageService::service()->uploadImage());
}
}
3. 业务逻辑层(OssImageService.php)
核心上传逻辑处理,包含文件命名、格式转换、上传执行:
<?php
declare(strict_types = 1);
namespace app\services;
use app\extensions\AliOss;
use OSS\Core\OssException;
class OssImageService extends BaseService
{
/**
* 执行 OSS 文件上传
* @return array 上传结果数据
* @throws OssException
*/
public function uploadImage()
{
// 1. 验证文件是否上传成功
if (empty($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) {
throw new \RuntimeException('文件上传失败,请检查文件大小和格式');
}
// 2. 获取 OSS 客户端实例和存储空间名称
$ossClient = AliOss::getOssClient();
$bucketName = AliOss::getBucketName();
// 3. 处理文件信息
$originalFileName = $_FILES['image']['name']; // 原始文件名
$tmpFilePath = $_FILES['image']['tmp_name']; // 服务器临时文件路径
$fileExt = $this->getExtension($originalFileName); // 文件扩展名
// 4. 构建 OSS 存储路径(按日期分类,避免文件名重复)
$ossDir = 'test/' . date('Y-m-d') . '/'; // 存储目录:test/年-月-日/
$ossFileName = date('Hi') . mt_rand(10000, 99999); // 文件名:时分+5位随机数
$ossObject = $ossDir . $ossFileName . '.' . $fileExt; // 完整 OSS 对象路径
// 5. 执行文件上传
$uploadResult = $ossClient->uploadFile($bucketName, $ossObject, $tmpFilePath);
// 6. 处理返回 URL(HTTP 转 HTTPS,提升安全性)
$ossUrl = $uploadResult['oss-request-url'];
if (strpos($ossUrl, 'http://') === 0) {
$ossUrl = str_replace('http://', 'https://', $ossUrl);
}
// 7. 组装返回数据
return [
'status' => 1,
'msg' => '上传成功',
'data' => [
'file_url' => $ossUrl, // 文件访问 URL
'file_name' => basename($ossUrl), // 文件名
'original_name' => $originalFileName, // 原始文件名(新增)
'file_size' => $_FILES['image']['size'] // 文件大小(新增)
]
];
}
/**
* 获取文件扩展名(兼容各种文件名格式)
* @param string $fileName 原始文件名
* @return string 扩展名(小写)
*/
private function getExtension(string $fileName): string
{
$ext = pathinfo($fileName, PATHINFO_EXTENSION);
return strtolower($ext);
}
}
4. OSS 配置封装(AliOss.php)
集中管理 OSS 配置参数,便于维护:
<?php
declare(strict_types = 1);
namespace app\extensions;
use OSS\OssClient;
use OSS\Core\OssException;
class AliOss
{
// 配置参数(建议移至环境变量或配置文件,避免硬编码)
const ENDPOINT = 'oss-cn-hongkong.aliyuncs.com';
const ACCESS_KEY_ID = 'LSDFskkdDDSSdkfg';
const ACCESS_KEY_SECRET = 'LT9cG3JkGKffRPalgk4n33lk8Ll41d';
const BUCKET = 'hk-server';
/**
* 获取 OSS 客户端实例
* @return OssClient|null OSS 客户端对象
*/
public static function getOssClient()
{
try {
// 初始化 OSS 客户端(false 表示不开启 CNAME)
return new OssClient(
self::ACCESS_KEY_ID,
self::ACCESS_KEY_SECRET,
self::ENDPOINT,
false
);
} catch (OssException $e) {
// 异常日志记录(建议替换为项目日志组件)
error_log('OSS 客户端初始化失败:' . $e->getMessage());
return null;
}
}
/**
* 获取存储空间名称
* @return string Bucket 名称
*/
public static function getBucketName(): string
{
return self::BUCKET;
}
}
上传结果与使用说明
1. 接口返回格式
上传成功后,前端将收到以下 JSON 响应:
{
"status": 1,
"msg": "上传成功",
"data": {
"file_url": "https://hk-server.oss-cn-hongkong.aliyuncs.com/test/2018-08-22/211753008.jpg",
"file_name": "211753008.jpg",
"original_name": "IMG_2023.jpg",
"file_size": 204800
}
}
2. 后续操作建议
-
前端接收
file_url后,需调用额外接口将文件信息(URL、原始文件名、分类、上传人等)存储到本地数据库,便于后续管理; -
直接访问返回的
file_url即可查看/下载文件,同时可在阿里云 OSS 控制台的对应 Bucket 中找到上传的文件。
常见问题排查
1. 访问密钥错误
-
错误提示:
The OSS Access Key Id you provided does not exist in our records -
解决方案:重新生成 AccessKeyId 和 AccessKeySecret,确保配置文件中的参数与控制台一致。
2. 文件上传失败
-
可能原因:
-
临时文件路径权限不足(检查服务器
tmp目录权限); -
文件大小超过 PHP 配置限制(调整
php.ini中的upload_max_filesize和post_max_size); -
OSS 存储空间权限设置不当(需确保 AccessKey 拥有上传权限)。
-
3. 其他错误
参考 阿里云 OSS 官方错误排查文档,根据错误码定位问题。
后续优化方向
1. 安全优化
将 AccessKey 等敏感信息移至.env环境变量或配置文件,避免硬编码在代码中;
2. 文件验证
增加文件类型、大小、后缀名验证,防止恶意文件上传;
3. 异常处理
完善异常捕获和日志记录,便于问题排查;
4. 性能优化
大文件建议使用分片上传,避免单次上传超时;
5. 权限控制
OSS 存储空间建议设置合理的访问权限,必要时使用 URL 签名过期机制。


