本文介紹如何在受版本控制的儲存空間(Bucket)中上傳檔案(Object)。
注意事項
本文以華東1(杭州)外網Endpoint為例。如果您希望通過與OSS同地區的其他阿里雲產品訪問OSS,請使用內網Endpoint。關於OSS支援的Region與Endpoint的對應關係,請參見OSS地區和訪問網域名稱。
本文以OSS網域名稱建立OSSClient為例。如果您希望通過自訂網域名、STS等方式建立OSSClient,請參見建立OssClient。
要上傳檔案,您必須有
oss:PutObject
許可權。具體操作,請參見為RAM使用者授權自訂的權限原則。
簡單上傳
在已開啟版本控制的Bucket中,OSS將為新上傳的Object產生全域唯一的隨機字串版本ID,並在響應Header中通過x-oss-version-id
形式返回。
在暫停了版本控制的Bucket中,OSS將為新上傳的Object產生特殊字元串為“null”的版本ID。上傳同名Object時,後一次會覆蓋前一次上傳的檔案內容,即同一個Object僅有一個版本的ID為“null”。
以下代碼用於簡單上傳:
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$provider = new EnvironmentVariableCredentialsProvider();
// Endpoint以杭州為例,其它Region請按實際情況填寫。
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
$bucket= "<yourBucketName>";
// 填寫不包含Bucket名稱在內的Object的完整路徑,例如example/test.txt。
$object = "<yourObjectName>";
$content = "hello world";
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
try {
// 在受版本控制的Bucket中上傳Object。
$ret = $ossClient->putObject($bucket, $object, $content);
// 查看Object的版本資訊。
print("versionId:" .$ret[OssClient::OSS_HEADER_VERSION_ID]);
} catch (OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": OK" . "\n");
簡單上傳的詳細資料請參見PutObject。
追加上傳
在受版本控制的Bucket中對Object進行追加上傳(AppendObject)操作時,有如下注意事項:
僅支援對目前的版本為Appendable類型的Object執行AppendObject操作。
不支援對歷史版本為Appendable類型或目前的版本為非Appendable類型的Object(包括Normal Object、Delete Marker等)執行AppendObject操作。
對目前的版本為Appendable類型的Object執行AppendObject操作時,OSS不會為該Appendable類型的Object產生歷史版本。
對目前的版本為Appendable類型的Object執行PutObject或DeleteObject操作時,OSS會將該Appendable類型的Object保留為歷史版本,且該Object不允許繼續追加。
以下代碼用於追加上傳:
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$provider = new EnvironmentVariableCredentialsProvider();
// Endpoint以杭州為例,其它Region請按實際情況填寫。
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
$bucket= "<yourBucketName>";
$object = "<yourObjectName>";
// 表示第一次、第二次以及第三次追加上傳後擷取的檔案內容分別為Hello OSS、Hi OSS以及OSS OK。
$content_array = array('Hello OSS', 'Hi OSS', 'OSS OK');
try{
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
// 第一次追加上傳。第一次追加的位置是0,傳回值為下一次追加的位置。後續追加的位置是追加前檔案的長度。
$position = $ossClient->appendObject($bucket, $object, $content_array[0], 0);
$position = $ossClient->appendObject($bucket, $object, $content_array[1], $position);
$position = $ossClient->appendObject($bucket, $object, $content_array[2], $position);
} catch(OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": OK" . "\n");
追加上傳的詳細資料請參見AppendObject。
分區上傳
在受版本控制的Bucket中,調用CompleteMultipartUpload介面來完成整個檔案的分區上傳,OSS會為整個檔案產生唯一的版本ID,並在響應Header中以x-oss-version-id
的形式返回。
以下代碼用於分區上傳:
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
use OSS\Core\OssUtil;
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$provider = new EnvironmentVariableCredentialsProvider();
// Endpoint以杭州為例,其它Region請按實際情況填寫。
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
$bucket= "<yourBucketName>";
$object = "<yourObjectName>";
// 填寫本地檔案的完整路徑。
$uploadFile = "<yourLocalFile>";
/**
* 步驟1:初始化一個分區上傳事件,擷取uploadId。
*/
try{
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
// 返回uploadId。uploadId是分區上傳事件的唯一標識。您可以根據uploadId發起相關的操作,如取消分區上傳、查詢分區上傳等。
$uploadId = $ossClient->initiateMultipartUpload($bucket, $object);
} catch(OssException $e) {
printf(__FUNCTION__ . ": initiateMultipartUpload FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": initiateMultipartUpload OK" . "\n");
/*
* 步驟2:上傳分區。
*/
$partSize = 10 * 1024 * 1024;
$uploadFileSize = sprintf('%u',filesize($uploadFile));
$pieces = $ossClient->generateMultiuploadParts($uploadFileSize, $partSize);
$responseUploadPart = array();
$uploadPosition = 0;
$isCheckMd5 = true;
foreach ($pieces as $i => $piece) {
$fromPos = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO];
$toPos = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1;
$upOptions = array(
// 上傳檔案。
$ossClient::OSS_FILE_UPLOAD => $uploadFile,
// 設定分區號。
$ossClient::OSS_PART_NUM => ($i + 1),
// 指定分區上傳起始位置。
$ossClient::OSS_SEEK_TO => $fromPos,
// 指定檔案長度。
$ossClient::OSS_LENGTH => $toPos - $fromPos + 1,
// 是否開啟MD5校正,true表示開啟,false表示未開啟。
$ossClient::OSS_CHECK_MD5 => $isCheckMd5,
);
// 開啟MD5校正。
if ($isCheckMd5) {
$contentMd5 = OssUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos);
$upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5;
}
try {
// 上傳分區。
$responseUploadPart[] = $ossClient->uploadPart($bucket, $object, $uploadId, $upOptions);
} catch(OssException $e) {
printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} FAILED\n");
printf($e->getMessage() . "\n");
return;
}
printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} OK\n");
}
// $uploadParts是由每個分區的ETag和分區號(PartNumber)組成的數組。
$uploadParts = array();
foreach ($responseUploadPart as $i => $eTag) {
$uploadParts[] = array(
'PartNumber' => ($i + 1),
'ETag' => $eTag,
);
}
/**
* 步驟3:完成上傳。
*/
try {
// 執行completeMultipartUpload操作時,需要提供所有有效$uploadParts。OSS收到提交的$uploadParts後,會逐一驗證每個分區的有效性。當所有的資料分區驗證通過後,OSS將把這些分區組合成一個完整的檔案。
$ret = $ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts);
// 查看Object版本資訊。
print("versionId:" .$ret[OssClient::OSS_HEADER_VERSION_ID]);
} catch(OssException $e) {
printf(__FUNCTION__ . ": completeMultipartUpload FAILED\n");
printf($e->getMessage() . "\n");
return;
}
printf(__FUNCTION__ . ": completeMultipartUpload OK\n");
分區上傳的詳細資料請參見InitiateMultipartUpload、UploadPart、CompleteMultipartUpload等介面。