本文目录导读:

在 PHP 项目中对接阿里云 OSS(对象存储服务),通常是为了实现文件的上传、下载和管理,最推荐的方式是使用阿里云官方提供的 OSS PHP SDK。
以下是完整的对接步骤和核心代码示例,涵盖了从安装到上传、下载的全过程。
第一步:准备工作
- 开通 OSS 服务:在阿里云控制台搜索“对象存储 OSS”,开通服务并创建一个 Bucket(存储空间)。
- 获取 AccessKey:
- 进入“RAM 访问控制” > “用户” > 创建一个专用用户(
oss-user)。 - 为该用户勾选“OpenAPI 调用”,并生成 AccessKey ID 和 AccessKey Secret。
- 重要:给这个用户授予 OSS 权限(如
AliyunOSSFullAccess),建议不要直接使用主账号的 AccessKey。
- 进入“RAM 访问控制” > “用户” > 创建一个专用用户(
第二步:安装 OSS PHP SDK
推荐使用 Composer 进行安装(确保服务器已安装 Composer):
composer require aliyuncs/oss-sdk-php
如果无法使用 Composer,也可以直接下载 SDK 文件手动引入,但 Composer 方式最省心。
第三步:配置与初始化
创建一个 ossService.php 或类似的封装类:
<?php
require_once __DIR__ . '/vendor/autoload.php'; // 引入 Composer 自动加载
use OSS\OssClient;
use OSS\Core\OssException;
class AliOssService
{
private $accessKeyId;
private $accessKeySecret;
private $endpoint; // 地域节点,oss-cn-hangzhou.aliyuncs.com
private $bucket; // 你的 Bucket 名称
private $ossClient;
public function __construct()
{
// 推荐从环境变量或配置文件读取,不要硬编码
$this->accessKeyId = getenv('OSS_ACCESS_KEY_ID') ?: 'your-access-key-id';
$this->accessKeySecret = getenv('OSS_ACCESS_SECRET') ?: 'your-access-key-secret';
$this->endpoint = getenv('OSS_ENDPOINT') ?: 'oss-cn-hangzhou.aliyuncs.com';
$this->bucket = getenv('OSS_BUCKET') ?: 'your-bucket-name';
try {
$this->ossClient = new OssClient(
$this->accessKeyId,
$this->accessKeySecret,
$this->endpoint
);
} catch (OssException $e) {
// 记录错误日志
throw new \Exception('OSS 初始化失败: ' . $e->getMessage());
}
}
// ... 接下来添加具体操作方法
}
第四步:核心功能实现
上传文件(本地文件)
/**
* 上传本地文件到 OSS
* @param string $localFile 本地文件路径,如 '/tmp/avatar.jpg'
* @param string $ossPath 在 OSS 上的存储路径,如 'images/2024/avatar.jpg'
* @return bool|string 成功返回 OSS 文件 URL,失败返回 false
*/
public function uploadFile($localFile, $ossPath)
{
try {
$result = $this->ossClient->uploadFile(
$this->bucket,
$ossPath,
$localFile
);
// 返回文件的公共可访问 URL(需 Bucket 权限允许)
return $result['info']['url'] ?? $this->getUrl($ossPath);
} catch (OssException $e) {
// 处理错误
error_log('OSS Upload Error: ' . $e->getMessage());
return false;
}
}
上传文件内容(字符串或二进制流)
适用于接收 POST 上传的图片数据:
/**
* 上传字符串内容(base64 解码后的图片数据)
* @param string $content 文件内容(二进制字符串)
* @param string $ossPath OSS 路径
* @return bool|string
*/
public function uploadContent($content, $ossPath)
{
try {
$result = $this->ossClient->putObject(
$this->bucket,
$ossPath,
$content
);
return $this->getUrl($ossPath);
} catch (OssException $e) {
error_log('OSS Upload Content Error: ' . $e->getMessage());
return false;
}
}
下载文件
/**
* 将 OSS 上的文件下载到本地
* @param string $ossPath OSS 路径
* @param string $localFile 本地保存路径
* @return bool
*/
public function downloadFile($ossPath, $localFile)
{
try {
$result = $this->ossClient->getObject(
$this->bucket,
$ossPath,
['saveAs' => $localFile] // 直接保存到文件
);
return true;
} catch (OssException $e) {
error_log('OSS Download Error: ' . $e->getMessage());
return false;
}
}
删除文件
public function deleteFile($ossPath)
{
try {
$this->ossClient->deleteObject($this->bucket, $ossPath);
return true;
} catch (OssException $e) {
error_log('OSS Delete Error: ' . $e->getMessage());
return false;
}
}
生成文件访问 URL(私有 Bucket 使用)
如果你的 Bucket 是私有的(推荐),你可以生成带签名的临时 URL:
/**
* 生成私有文件的临时访问 URL(带过期时间)
* @param string $ossPath
* @param int $expireSeconds 过期秒数,默认 3600s(1小时)
* @return string
*/
public function getSignedUrl($ossPath, $expireSeconds = 3600)
{
try {
return $this->ossClient->signUrl(
$this->bucket,
$ossPath,
$expireSeconds
);
} catch (OssException $e) {
error_log('OSS Sign URL Error: ' . $e->getMessage());
return '';
}
}
第五步:完整调用示例(控制器中)
<?php
// 假设在你的控制器方法中
public function uploadAvatar()
{
if (empty($_FILES['avatar'])) {
return json(['code' => 400, 'msg' => '文件未上传']);
}
$file = $_FILES['avatar'];
$ext = pathinfo($file['name'], PATHINFO_EXTENSION); // 后缀
$newFileName = 'avatars/' . date('Ymd') . '/' . uniqid() . '.' . $ext;
// 实例化 OSS 服务
$ossService = new AliOssService();
$filePath = $file['tmp_name'];
$url = $ossService->uploadFile($filePath, $newFileName);
if ($url) {
// 保存 $url 到数据库用户头像字段
return json(['code' => 200, 'url' => $url]);
} else {
return json(['code' => 500, 'msg' => '上传失败']);
}
}
第六步:常见问题与优化建议
权限设置(Bucket Policy)
- 私有 Bucket(推荐):只能通过签名 URL 访问,安全性高,适合用户头像、订单附件等。
- 公共读 Bucket:对象可通过 URL 直接访问(
https://bucket.oss-cn-hangzhou.aliyuncs.com/file.jpg),适合网站静态资源,但要注意防盗链。
防盗链(Referer)
在 Bucket 设置中开启防盗链,只允许你的网站域名访问,防止外站盗用 OSS 流量。
使用内网 Endpoint
如果你的 PHP 服务器也部署在阿里云(ECS),且与 OSS Bucket 在同一地域,使用 内网 Endpoint(如 oss-cn-hangzhou-internal.aliyuncs.com)可以免流量费,速度更快。
大文件分片上传
上传超过 100MB 的文件,建议使用分片上传:
// 初始化分片 $uploadId = $this->ossClient->initiateMultipartUpload($bucket, $object); // 循环上传分片 $this->ossClient->uploadPart($bucket, $object, $uploadId, ...); // 完成上传 $this->ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts);
SDK 也提供了更简单的 multiuploadFile 方法一键分片。
安全警告
- 绝对不要把 AccessKey Secret 写在代码里或上传到 GitHub,永远使用环境变量
$_ENV或配置中心。 - 生产环境建议使用 STS 临时凭证,通过 RAM Role 授权给应用,临时凭证几个小时过期,更安全。
错误排查
如果上传失败,先检查:
endpoint是否正确(如oss-cn-beijing.aliyuncs.com,注意不要带https://)。accessKeyId是否有对应 Bucket 的权限。- Bucket 名称是否拼写正确(Bucket 名全局唯一)。
对接阿里云 OSS 的核心流程就是:
- 创建 Bucket + 获取 AccessKey。
- 安装 SDK (
composer require aliyuncs/oss-sdk-php)。 - 初始化 OssClient。
- 调用
uploadFile/putObject/signUrl等方法。
按照上述步骤,你就可以在 PHP 项目中顺利使用阿里云 OSS 了。