我熟悉 Google Drive 和 Microsoft OneDrive 这类典型的云存储服务。不过,在网页开发中,这些云存储提供商并不太合适,因为它们缺少指向已上传文件的直接、永久链接。为了解决这个问题,对象存储就成了一个方便又可靠的方案。
在本文中,我会使用 IPServerOne 提供的对象存储,而不是 Amazon S3。过程几乎相同;你只需要相应地更改 $s3_endpoint 变量。
小贴士:如果你不熟悉 PHP,可以请 ChatGPT/Copilot 将 PHP 代码逆向转换成 cURL 命令。
上传到 S3
要将文件上传到对象存储提供商,你只需要传入正确的参数并执行一个 cURL 请求。其实非常简单直接——就像发起典型的 REST API 调用一样。
关键逻辑: 上传逻辑的核心是使用 curl_init 打开连接到 S3 端点的连接,然后使用 CURLOPT_PUT 直接流式传输文件内容。这种方法非常高效,因为它避免了大型第三方库的开销。
<?php
$file_to_upload = 'yourimage.png';
$bucket = 'wordpressha';
$s3_endpoint = 'ap-southeast-mys1.oss.ips1cloud.com';
$access_key = '5IRK7V7TVSV0B829WHAD';
$secret_key = 'I7BLtOZAsHdCDHMeyJ73QipBIPjLDCvWhIAzfynV';
$content_type = 'application/octet-stream';
$date_value = gmdate('D, d M Y H:i:s T');
$string_to_sign = "PUTnn{$content_type}n{$date_value}n/{$bucket}/{$file_to_upload}";
$signature = base64_encode(hash_hmac('sha1', $string_to_sign, $secret_key, true));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://{$bucket}.{$s3_endpoint}/{$file_to_upload}");
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, fopen($file_to_upload, 'r'));
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file_to_upload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Host: {$bucket}.{$s3_endpoint}",
"Date: {$date_value}",
"Content-Type: {$content_type}",
"Authorization: AWS {$access_key}:{$signature}"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code == 200) {
echo "File uploaded successfully.";
} else {
echo "Failed to upload file. HTTP Status Code: {$http_code}";
}
演示 💻
这个演示展示了文件如何直接上传到对象存储:
访问私有存储桶文件(从 S3 下载)
存储在公共存储桶中的对象(文件)可以通过其 URL 直接访问。不过,对于私有存储桶,URL 需要在查询字符串中加入额外的身份验证参数才能授予访问权限。
关键逻辑: 生成预签名 URL 的方法是使用 hash_hmac 和你的 Secret Key 对过期时间及存储桶路径进行哈希运算。由于这是客户端计算,此步骤不需要调用 API,因此速度极快。
<?php
$object_key = 'yourimage.png';
$bucket = 'wordpressha';
$s3_endpoint = 'ap-southeast-mys1.oss.ips1cloud.com';
$access_key = '5IRK7V7TVSV0B829WHAD';
$secret_key = 'I7BLtOZAsHdCDHMeyJ73QipBIPjLDCvWhIAzfynV';
$expires = time() + 3600;
$method = 'GET';
$string_to_sign = "{$method}nnn{$expires}n/{$bucket}/{$object_key}";
$signature = base64_encode(hash_hmac('sha1', $string_to_sign, $secret_key, true));
$presigned_url = "https://{$bucket}.{$s3_endpoint}/{$object_key}?AWSAccessKeyId={$access_key}&Expires={$expires}&Signature=" . urlencode($signature);
echo "Presigned URL: {$presigned_url}n";
通过公共存储桶访问对象的示例
| https://ap-southeast-mys1.oss.ips1cloud.com/wordpressha/test.jpg |
通过私有存储桶访问对象的示例
| https://wordpressha.ap-southeast-mys1.oss.ips1cloud.com/test.jpg?AWSAccessKeyId=KL6FSI64D6FEBHY77621&Expires=1734687785&Signature=4zRuNtWz%2F9ewHT%2FUF7c2mCfOxco%3D |
注意附加在 URL 后面的
AWSAccessKeyId、Expires和Signature参数。这称为预签名 URL。
回看代码,你会注意到生成预签名 URL 并不涉及 API 调用。它纯粹是根据用你的 Secret Key 加盐的字符串所生成的哈希值来计算。
演示 💻
这个演示说明了如何访问私有存储桶中的文件:
不用担心尝试访问测试存储桶——访问权限已经被撤销。这些示例只是为了本文而创建 😉。
到这里,你应该已经清楚了解对象存储如何运作,以及如何用纯 PHP 将它集成起来!😇

发表回复
要发表评论,您必须先登录。