PHP项目如何对接阿里云OSS?

wen PHP项目 2

本文目录导读:

PHP项目如何对接阿里云OSS?

  1. 安装SDK
  2. 基本配置
  3. 常用操作示例
  4. 生成访问URL
  5. 完整使用示例
  6. 安全建议
  7. 常见问题

我来详细介绍PHP项目对接阿里云OSS的完整流程。

安装SDK

使用Composer安装

composer require aliyuncs/oss-sdk-php

或手动下载

阿里云OSS PHP SDK下载并引入

基本配置

获取阿里云OSS配置信息

  • AccessKey ID
  • AccessKey Secret
  • Bucket名称
  • Endpoint(地域节点)

配置示例

<?php
require_once __DIR__ . '/vendor/autoload.php';
use OSS\OssClient;
use OSS\Core\OssException;
// OSS配置
$config = [
    'accessKeyId'     => 'your-access-key-id',
    'accessKeySecret' => 'your-access-key-secret',
    'endpoint'        => 'oss-cn-hangzhou.aliyuncs.com', // 根据实际地域修改
    'bucket'          => 'your-bucket-name',
    'isCName'         => false, // 是否使用自定义域名
];
try {
    $ossClient = new OssClient(
        $config['accessKeyId'],
        $config['accessKeySecret'],
        $config['endpoint'],
        $config['isCName']
    );
} catch (OssException $e) {
    die("OSS连接失败: " . $e->getMessage());
}

常用操作示例

文件上传

上传本地文件

function uploadFile($ossClient, $bucket, $localFile, $ossPath) {
    try {
        // 上传文件
        $result = $ossClient->uploadFile(
            $bucket,
            $ossPath,
            $localFile
        );
        echo "上传成功,文件URL: " . $result['oss-request-url'];
        return $result;
    } catch (OssException $e) {
        echo "上传失败: " . $e->getMessage();
        return false;
    }
}
// 使用示例
$localFile = '/path/to/local/image.jpg';
$ossPath = 'images/2024/01/image.jpg';
uploadFile($ossClient, $bucket, $localFile, $ossPath);

上传字符串内容

function uploadContent($ossClient, $bucket, $content, $ossPath) {
    try {
        $result = $ossClient->putObject(
            $bucket,
            $ossPath,
            $content
        );
        return $result;
    } catch (OssException $e) {
        echo "上传失败: " . $e->getMessage();
        return false;
    }
}
// 使用示例
$content = file_get_contents('path/to/file');
$ossPath = 'documents/report.txt';
uploadContent($ossClient, $bucket, $content, $ossPath);

文件下载

下载到本地

function downloadFile($ossClient, $bucket, $ossPath, $localPath) {
    try {
        $result = $ossClient->getObject(
            $bucket,
            $ossPath,
            [
                'save_as' => $localPath
            ]
        );
        echo "下载成功";
        return true;
    } catch (OssException $e) {
        echo "下载失败: " . $e->getMessage();
        return false;
    }
}
// 使用示例
$ossPath = 'images/2024/01/image.jpg';
$localPath = '/tmp/downloaded_image.jpg';
downloadFile($ossClient, $bucket, $ossPath, $localPath);
function getObjectContent($ossClient, $bucket, $ossPath) {
    try {
        $content = $ossClient->getObject(
            $bucket,
            $ossPath
        );
        return $content;
    } catch (OssException $e) {
        echo "获取失败: " . $e->getMessage();
        return false;
    }
}

文件管理

删除文件

function deleteFile($ossClient, $bucket, $ossPath) {
    try {
        $ossClient->deleteObject($bucket, $ossPath);
        echo "删除成功";
        return true;
    } catch (OssException $e) {
        echo "删除失败: " . $e->getMessage();
        return false;
    }
}

文件列表

function listFiles($ossClient, $bucket, $prefix = '') {
    try {
        $options = [
            'max-keys' => 100, // 最大返回数量
            'prefix'   => $prefix, // 文件前缀筛选
        ];
        $list = $ossClient->listObjects($bucket, $options);
        $files = [];
        foreach ($list->getObjectList() as $object) {
            $files[] = [
                'key'       => $object->getKey(),
                'size'      => $object->getSize(),
                'lastModified' => $object->getLastModified(),
                'url'       => getFileUrl($object->getKey())
            ];
        }
        return $files;
    } catch (OssException $e) {
        echo "获取列表失败: " . $e->getMessage();
        return [];
    }
}

生成访问URL

生成公开文件的URL

function getFileUrl($ossPath) {
    global $config;
    return "https://{$config['bucket']}.{$config['endpoint']}/{$ossPath}";
}

生成私有文件的临时URL(带签名)

function getSignedUrl($ossClient, $bucket, $ossPath, $expireTime = 3600) {
    try {
        $url = $ossClient->signUrl(
            $bucket,
            $ossPath,
            $expireTime // 过期时间,单位秒
        );
        return $url;
    } catch (OssException $e) {
        echo "生成URL失败: " . $e->getMessage();
        return false;
    }
}
// 使用示例:生成1小时有效的URL
$url = getSignedUrl($ossClient, $bucket, 'private/document.pdf', 3600);

完整使用示例

Web上传控制器示例

<?php
namespace App\Controller;
use OSS\OssClient;
use OSS\Core\OssException;
class FileUploadController
{
    private $ossClient;
    private $config;
    public function __construct()
    {
        $this->config = [
            'accessKeyId'     => 'your-access-key-id',
            'accessKeySecret' => 'your-access-key-secret',
            'endpoint'        => 'oss-cn-hangzhou.aliyuncs.com',
            'bucket'          => 'your-bucket-name',
        ];
        $this->initOssClient();
    }
    private function initOssClient()
    {
        try {
            $this->ossClient = new OssClient(
                $this->config['accessKeyId'],
                $this->config['accessKeySecret'],
                $this->config['endpoint']
            );
        } catch (OssException $e) {
            throw new \Exception('OSS初始化失败');
        }
    }
    public function uploadImage($request)
    {
        $file = $request->file('image');
        if (!$file->isValid()) {
            return ['code' => 400, 'message' => '文件无效'];
        }
        // 允许的文件类型
        $allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
        if (!in_array($file->getMimeType(), $allowedTypes)) {
            return ['code' => 400, 'message' => '不支持的文件类型'];
        }
        // 生成OSS路径
        $ext = $file->getClientOriginalExtension();
        $ossPath = 'uploads/' . date('Y/m/d') . '/' . 
                   uniqid() . '.' . $ext;
        try {
            // 上传到OSS
            $result = $this->ossClient->uploadFile(
                $this->config['bucket'],
                $ossPath,
                $file->getRealPath()
            );
            // 返回文件信息
            return [
                'code' => 200,
                'data' => [
                    'url' => $this->getFileUrl($ossPath),
                    'path' => $ossPath,
                    'size' => $file->getSize()
                ]
            ];
        } catch (OssException $e) {
            return ['code' => 500, 'message' => '上传失败'];
        }
    }
    private function getFileUrl($ossPath)
    {
        return "https://{$this->config['bucket']}.{$this->config['endpoint']}/{$ossPath}";
    }
}

安全建议

使用RAM子账号

// 使用RAM子账号的AccessKey
$config = [
    'accessKeyId'     => 'ram-user-access-key-id',
    'accessKeySecret' => 'ram-user-access-key-secret',
    // ... 其他配置
];

使用临时凭证(STS)

use OSS\OssClient;
use Sts\Core\StsClient;
// 获取STS临时凭证
$stsClient = new StsClient([
    'regionId'    => 'cn-hangzhou',
    'accessKeyId' => 'parent-access-key-id',
    'accessSecret'=> 'parent-access-key-secret',
]);
$token = $stsClient->assumeRole([
    'RoleArn'         => 'acs:ram::123456789:role/oss-upload-role',
    'RoleSessionName' => 'upload-session',
    'DurationSeconds' => 3600,
]);
// 使用临时凭证初始化OSS
$ossClient = new OssClient(
    $token['Credentials']['AccessKeyId'],
    $token['Credentials']['AccessKeySecret'],
    $config['endpoint'],
    false,
    $token['Credentials']['SecurityToken']
);

常见问题

  1. 跨域问题:需要在OSS控制台设置CORS规则
  2. 大文件上传:使用分片上传功能
  3. 权限问题:确保Bucket权限设置正确
  4. 网络问题:检查Endpoint配置是否正确

这套方案可以满足大多数PHP项目的OSS对接需求,根据实际场景,你可能需要调整上传策略、添加日志记录、实现重试机制等。

抱歉,评论功能暂时关闭!