PHP腾讯云COS对接

wen PHP项目 2

本文目录导读:

PHP腾讯云COS对接

  1. 安装依赖
  2. 基础配置
  3. 使用方法示例
  4. 前端上传示例 upload_form.html
  5. 配置文件说明
  6. 注意事项

我来帮你实现PHP对接腾讯云COS(对象存储),提供完整的示例代码和说明。

安装依赖

使用Composer安装腾讯云COS的PHP SDK:

composer require qcloud/cos-sdk-v5

基础配置

1 配置文件 cos_config.php

<?php
return [
    'secretId' => '你的SecretId',
    'secretKey' => '你的SecretKey',
    'region' => 'ap-guangzhou', // 你的地域
    'bucket' => 'example-1250000000', // 存储桶名称
    'cdn_domain' => 'https://cdn.example.com', // CDN域名(可选)
];

2 基础类 CosClient.php

<?php
require_once 'vendor/autoload.php';
use Qcloud\Cos\Client;
use Qcloud\Cos\Exception\ServiceResponseException;
class CosClient
{
    private $client;
    private $config;
    public function __construct()
    {
        $this->config = require 'cos_config.php';
        $this->client = new Client([
            'region' => $this->config['region'],
            'credentials' => [
                'secretId' => $this->config['secretId'],
                'secretKey' => $this->config['secretKey']
            ]
        ]);
    }
    /**
     * 上传文件(通过本地路径)
     */
    public function uploadFile($localPath, $cosPath, $options = [])
    {
        try {
            $result = $this->client->putObject([
                'Bucket' => $this->config['bucket'],
                'Key' => $cosPath,
                'SourceFile' => $localPath,
                ...$options
            ]);
            return $this->getFileUrl($cosPath);
        } catch (ServiceResponseException $e) {
            throw new Exception('上传失败: ' . $e->getMessage());
        }
    }
    /**
     * 上传文件内容(字符串)
     */
    public function uploadContent($content, $cosPath, $options = [])
    {
        try {
            $result = $this->client->putObject([
                'Bucket' => $this->config['bucket'],
                'Key' => $cosPath,
                'Body' => $content,
                ...$options
            ]);
            return $this->getFileUrl($cosPath);
        } catch (ServiceResponseException $e) {
            throw new Exception('上传失败: ' . $e->getMessage());
        }
    }
    /**
     * 下载文件
     */
    public function downloadFile($cosPath, $localPath)
    {
        try {
            $result = $this->client->getObject([
                'Bucket' => $this->config['bucket'],
                'Key' => $cosPath,
                'SaveAs' => $localPath
            ]);
            return true;
        } catch (ServiceResponseException $e) {
            throw new Exception('下载失败: ' . $e->getMessage());
        }
    }
    /**
     * 获取文件内容
     */
    public function getFileContent($cosPath)
    {
        try {
            $result = $this->client->getObject([
                'Bucket' => $this->config['bucket'],
                'Key' => $cosPath
            ]);
            return $result['Body']->getContents();
        } catch (ServiceResponseException $e) {
            throw new Exception('获取文件失败: ' . $e->getMessage());
        }
    }
    /**
     * 删除文件
     */
    public function deleteFile($cosPath)
    {
        try {
            $result = $this->client->deleteObject([
                'Bucket' => $this->config['bucket'],
                'Key' => $cosPath
            ]);
            return true;
        } catch (ServiceResponseException $e) {
            throw new Exception('删除失败: ' . $e->getMessage());
        }
    }
    /**
     * 批量删除文件
     */
    public function deleteFiles($cosPaths)
    {
        try {
            $objects = [];
            foreach ($cosPaths as $path) {
                $objects[] = ['Key' => $path];
            }
            $result = $this->client->deleteObjects([
                'Bucket' => $this->config['bucket'],
                'Objects' => $objects
            ]);
            return true;
        } catch (ServiceResponseException $e) {
            throw new Exception('批量删除失败: ' . $e->getMessage());
        }
    }
    /**
     * 获取文件URL
     */
    public function getFileUrl($cosPath)
    {
        return $this->client->getObjectUrl(
            $this->config['bucket'],
            $cosPath,
            '+10 minutes'
        );
    }
    /**
     * 获取永久URL(普通访问)
     */
    public function getPermanentUrl($cosPath)
    {
        if (isset($this->config['cdn_domain'])) {
            return $this->config['cdn_domain'] . '/' . $cosPath;
        }
        return sprintf(
            'https://%s.cos.%s.myqcloud.com/%s',
            $this->config['bucket'],
            $this->config['region'],
            $cosPath
        );
    }
    /**
     * 分片上传(大文件)
     */
    public function multipartUpload($localPath, $cosPath, $partSize = 5 * 1024 * 1024)
    {
        try {
            $result = $this->client->upload(
                $this->config['bucket'],
                $cosPath,
                fopen($localPath, 'rb'),
                [
                    'partSize' => $partSize,
                    'concurrency' => 3
                ]
            );
            return $this->getFileUrl($cosPath);
        } catch (ServiceResponseException $e) {
            throw new Exception('分片上传失败: ' . $e->getMessage());
        }
    }
    /**
     * 基于文件的元数据信息
     */
    public function getFileInfo($cosPath)
    {
        try {
            $result = $this->client->headObject([
                'Bucket' => $this->config['bucket'],
                'Key' => $cosPath
            ]);
            return [
                'size' => $result['ContentLength'],
                'contentType' => $result['ContentType'],
                'etag' => $result['ETag'],
                'lastModified' => $result['LastModified']
            ];
        } catch (ServiceResponseException $e) {
            throw new Exception('获取文件信息失败: ' . $e->getMessage());
        }
    }
    /**
     * 列出所有文件
     */
    public function listFiles($prefix = '', $marker = '', $limit = 1000)
    {
        try {
            $result = $this->client->listObjects([
                'Bucket' => $this->config['bucket'],
                'Prefix' => $prefix,
                'Marker' => $marker,
                'MaxKeys' => $limit
            ]);
            $files = [];
            if (isset($result['Contents'])) {
                foreach ($result['Contents'] as $content) {
                    $files[] = [
                        'key' => $content['Key'],
                        'size' => $content['Size'],
                        'lastModified' => $content['LastModified']
                    ];
                }
            }
            return $files;
        } catch (ServiceResponseException $e) {
            throw new Exception('列出文件失败: ' . $e->getMessage());
        }
    }
    /**
     * 设置文件访问权限
     */
    public function setFileAcl($cosPath, $acl = 'public-read')
    {
        try {
            $result = $this->client->putObjectAcl([
                'Bucket' => $this->config['bucket'],
                'Key' => $cosPath,
                'ACL' => $acl
            ]);
            return true;
        } catch (ServiceResponseException $e) {
            throw new Exception('设置权限失败: ' . $e->getMessage());
        }
    }
    /**
     * 生成预签名URL
     */
    public function generatePresignedUrl($cosPath, $expires = 3600)
    {
        try {
            $result = $this->client->getCommand('GetObject', [
                'Bucket' => $this->config['bucket'],
                'Key' => $cosPath
            ]);
            $request = $this->client->createPresignedRequest($result, "+{$expires} seconds");
            return (string)$request->getUri();
        } catch (Exception $e) {
            throw new Exception('生成预签名URL失败: ' . $e->getMessage());
        }
    }
    /**
     * 图片处理(缩略图等)
     */
    public function processImage($cosPath, $operations)
    {
        $url = $this->getPermanentUrl($cosPath);
        return $url . '?imageMogr2/' . $operations;
    }
}

使用方法示例

1 上传文件示例 upload_example.php

<?php
require_once 'CosClient.php';
$cos = new CosClient();
try {
    // 1. 上传本地文件
    $url = $cos->uploadFile(
        '/path/to/local/image.jpg',
        'images/products/2024/image.jpg',
        [
            'ContentType' => 'image/jpeg',
            'Metadata' => [
                'x-cos-meta-company' => 'example'
            ]
        ]
    );
    echo "上传成功: " . $url . "\n";
    // 2. 上传字符串内容
    $content = 'Hello COS';
    $url = $cos->uploadContent($content, 'text/hello.txt', [
        'ContentType' => 'text/plain'
    ]);
    echo "内容上传成功: " . $url . "\n";
    // 3. 分片上传大文件
    $url = $cos->multipartUpload('/path/to/large/video.mp4', 'videos/2024/video.mp4');
    echo "分片上传成功: " . $url . "\n";
} catch (Exception $e) {
    echo '错误: ' . $e->getMessage() . "\n";
}

2 文件管理示例 manage_example.php

<?php
require_once 'CosClient.php';
$cos = new CosClient();
try {
    // 1. 设置文件权限
    $cos->setFileAcl('images/logo.png', 'public-read');
    // 2. 获取文件信息
    $info = $cos->getFileInfo('images/logo.png');
    echo "文件大小: " . $info['size'] . " bytes\n";
    echo "文件类型: " . $info['contentType'] . "\n";
    // 3. 生成临时下载链接
    $tempUrl = $cos->generatePresignedUrl('images/logo.png', 3600);
    echo "临时下载链接: " . $tempUrl . "\n";
    // 4. 图片处理示例
    $thumbUrl = $cos->processImage('images/logo.png', 'thumbnail/200x200');
    echo "缩略图链接: " . $thumbUrl . "\n";
    // 5. 列出文件
    $files = $cos->listFiles('images/');
    foreach ($files as $file) {
        echo "文件: " . $file['key'] . " (" . $file['size'] . " bytes)\n";
    }
    // 6. 删除文件
    // $cos->deleteFile('text/hello.txt');
} catch (Exception $e) {
    echo '错误: ' . $e->getMessage() . "\n";
}

3 Web上传示例 web_upload.php

<?php
require_once 'CosClient.php';
$cos = new CosClient();
// 处理文件上传
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
    $file = $_FILES['file'];
    if ($file['error'] === UPLOAD_ERR_OK) {
        $directory = 'uploads/' . date('Y/m/d/');
        $fileName = uniqid() . '-' . basename($file['name']);
        $cosPath = $directory . $fileName;
        try {
            // 获取文件类型
            $mime = mime_content_type($file['tmp_name']);
            // 上传到COS
            $url = $cos->uploadFile(
                $file['tmp_name'],
                $cosPath,
                [
                    'ContentType' => $mime,
                    'ACL' => 'public-read'
                ]
            );
            // 返回JSON响应
            header('Content-Type: application/json');
            echo json_encode([
                'success' => true,
                'url' => $url,
                'path' => $cosPath
            ]);
        } catch (Exception $e) {
            header('Content-Type: application/json');
            echo json_encode([
                'success' => false,
                'message' => $e->getMessage()
            ]);
        }
    }
}
?>

前端上传示例 upload_form.html

<!DOCTYPE html>
<html>
<head>COS文件上传</title>
</head>
<body>
    <h1>文件上传到COS</h1>
    <form id="uploadForm" enctype="multipart/form-data">
        <input type="file" name="file" required>
        <button type="submit">上传</button>
    </form>
    <div id="result" style="display:none;">
        <h3>上传结果:</h3>
        <p id="fileUrl"></p>
        <img id="preview" style="max-width: 300px; display:none;">
    </div>
    <script>
        document.getElementById('uploadForm').addEventListener('submit', function(e) {
            e.preventDefault();
            const formData = new FormData(this);
            fetch('web_upload.php', {
                method: 'POST',
                body: formData
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    document.getElementById('result').style.display = 'block';
                    document.getElementById('fileUrl').textContent = '文件地址: ' + data.url;
                    // 如果是图片,显示预览
                    if (data.url.match(/\.(jpg|jpeg|png|gif|webp)$/i)) {
                        const img = document.getElementById('preview');
                        img.src = data.url;
                        img.style.display = 'block';
                    }
                    alert('上传成功!');
                } else {
                    alert('上传失败: ' + data.message);
                }
            })
            .catch(error => {
                alert('上传失败: ' + error.message);
            });
        });
    </script>
</body>
</html>

配置文件说明

cos_config.php 中填写你的COS配置:

  1. SecretId:腾讯云API密钥ID
  2. SecretKey:腾讯云API密钥Key
  3. Region:COS所在地域(如:ap-guangzhou, ap-beijing等)
  4. Bucket:存储桶名称(格式:名称-APPID)
  5. CDN域名:可选,用于提供加速访问

注意事项

  1. 安全设置:生产环境不要把密钥硬编码在代码中,建议使用环境变量
  2. 权限控制:合理设置文件ACL权限,敏感文件建议使用私有读
  3. 大文件:上传超过100MB的文件建议使用分片上传
  4. 错误处理:捕获并处理所有异常,返回友好提示
  5. HTTPS:建议开启CDN并配置HTTPS证书

这个示例代码涵盖了大多数常见的COS操作场景,你可以根据实际需求进行调整。

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