php - Azure 使用 REST API 将 Blob 从一个存储帐户复制到同一订阅中的另一个存储帐户

标签 php rest azure azure-blob-storage

我想使用 Rest API 和 PHP 将 blob 从一个存储帐户复制到同一订阅中的另一个存储帐户。我可以使用以下代码将 blob 从一个容器复制到同一存储帐户中的另一个容器

<?php    
$date = gmdate('D, d M Y H:i:s \G\M\T');
$account_name = "accname";
$destcontainername = "destcontainer";
$blobname = "blob.png";
$sourcecontainer = "sourcecontainer";    
$account_key = "asdf";

$canonicalizedHeaders = "x-ms-copy-source:https://".$account_name.".blob.core.windows.net/".$sourcecontainer."/".$blobname."\nx-ms-date:$date\nx-ms-version:2015-04-05";
$canonicalizedResource = "/$account_name/$destcontainername/$blobname";

$arraysign = array();
$arraysign[] = 'PUT';                     /*HTTP Verb*/  
$arraysign[] = '';                        /*Content-Encoding*/  
$arraysign[] = '';                        /*Content-Language*/  
$arraysign[] = '';                        /*Content-Length (include value when zero)*/  
$arraysign[] = '';                        /*Content-MD5*/  
$arraysign[] = '';                        /*Content-Type*/  
$arraysign[] = '';                        /*Date*/  
$arraysign[] = '';                        /*If-Modified-Since */  
$arraysign[] = '';                        /*If-Match*/  
$arraysign[] = '';                        /*If-None-Match*/  
$arraysign[] = '';                        /*If-Unmodified-Since*/  
$arraysign[] = '';                        /*Range*/  
$arraysign[] = $canonicalizedHeaders;     /*CanonicalizedHeaders*/
$arraysign[] = $canonicalizedResource;    /*CanonicalizedResource*/

$stringtosign = implode("\n", $arraysign);

$signature = 'SharedKey'.' '.$account_name.':'.base64_encode(hash_hmac('sha256', $stringtosign, base64_decode($account_key), true));

$endpoint = 'https://'.$account_name.'.blob.core.windows.net';
$url = $endpoint.'/'.$destcontainername.'/'.$blobname;

$headers = [
    'x-ms-copy-source:https://'.$account_name.'.blob.core.windows.net/'.$sourcecontainer.'/'.$blobname,
    "x-ms-date:{$date}",
    'x-ms-version:2015-04-05',
    'Accept:application/json;odata=nometadata',
    'Accept-Charset:UTF-8',
    'Content-Length:0',
    "Authorization:{$signature}"
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
$response  = curl_exec($ch);
echo curl_error($ch);
curl_close($ch);        

echo '<pre>';print_r($response);

我想知道是否必须使用相同的复制 blob Rest API 来完成它。如果是,则 $canonicalizedHeaders$canonicalizedResource 以及请求剩余 API 是什么。我可以使用下面的 powershell 命令将 blob 从一个存储帐户复制到另一个存储帐户

Start-AzureStorageBlobCopy -DestContainer $destinationContainerName -DestContext $destinationContext -SrcBlob $vhdName -Context $sourceContext -SrcContainer $sourceSAContainerName

最佳答案

您也可以使用相同的代码跨存储帐户复制 blob。虽然 $canonicalizedResource 保持不变,但您需要在 $canonicalizedHeadersx-ms-copy-source header 中包含源 Blob 的 URL >.

需要记住的一件重要事情是,您在 x-ms-copy-source header 中指定的源 Blob URL 必须可公开访问。这意味着,如果您获取该 URL 并将其粘贴到浏览器的地址栏中,您应该能够访问该 blob。如果源 Blob 容器的 ACL 为 BlobContainer,则您只需指定 Blob URL (https://sourceaccountname.blob.core.windows.net/sourceblobcontainer/sourceblobname),但是如果源 blob 容器的 ACL 是私有(private),那么您需要在源 blob 上创建一个共享访问签名 (SAS)至少具有读取权限并使用 SAS URL 作为此 header 的值。

另一件需要理解的事情是,跨存储帐户复制是一种异步操作。因此,当上面的代码执行成功时,blob 复制操作就会排队。在删除源 blob 或对其进行任何更改之前,必须检查复制操作是否已完成,否则复制操作将失败。

关于php - Azure 使用 REST API 将 Blob 从一个存储帐户复制到同一订阅中的另一个存储帐户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43494650/

相关文章:

php - 通过javascript发布php ajax结果时激活javascript

php - 在php中使用fpdf在pdf文件中创建饼图

RESTful - DELETE 响应正文应包含什么

azure - 不支持构造函数 'DisableAttribute(Type)'。为服务总线队列生成函数元数据时出错触发了 Azure 函数

azure - 更新 Azure DocumentDB 中文档的一部分

azure - Azure Data Lake Gen2 是否提供 WebHDFS REST API?

php - 如何在 XAMPP 服务器上使用 php 将 MySQL 数据库连接到 html 页面?

php - 显示特定记录的详细信息

javascript - 使用 AngularJs 从 PagedList(Web API) 获取集合中所有元素的数量

json - 如何在 YouTube API v3 中禁用评论