ConcurrentCopyPartSample.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <?php
  2. /**
  3. * Copyright 2019 Huawei Technologies Co.,Ltd.
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
  5. * this file except in compliance with the License. You may obtain a copy of the
  6. * License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software distributed
  11. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. * specific language governing permissions and limitations under the License.
  14. *
  15. */
  16. /**
  17. * This sample demonstrates how to multipart upload an object concurrently by copy mode
  18. * to OBS using the OBS SDK for PHP.
  19. */
  20. if (file_exists ( 'vendor/autoload.php' )) {
  21. require 'vendor/autoload.php';
  22. } else {
  23. require '../vendor/autoload.php'; // sample env
  24. }
  25. if (file_exists ( 'obs-autoloader.php' )) {
  26. require 'obs-autoloader.php';
  27. } else {
  28. require '../obs-autoloader.php'; // sample env
  29. }
  30. use Obs\ObsClient;
  31. use Obs\ObsException;
  32. $ak = '*** Provide your Access Key ***';
  33. $sk = '*** Provide your Secret Key ***';
  34. $endpoint = 'https://your-endpoint:443';
  35. $bucketName = 'my-obs-bucket-demo';
  36. $sourceBucketName = $bucketName;
  37. $sourceObjectKey = 'my-obs-object-key-demo';
  38. $objectKey = $sourceObjectKey . '-back';
  39. /*
  40. * Constructs a obs client instance with your account for accessing OBS
  41. */
  42. $obsClient = ObsClient::factory ( [
  43. 'key' => $ak,
  44. 'secret' => $sk,
  45. 'endpoint' => $endpoint,
  46. 'socket_timeout' => 30,
  47. 'connect_timeout' => 10
  48. ] );
  49. try
  50. {
  51. /*
  52. * Create bucket
  53. */
  54. printf("Create a new bucket for demo\n\n");
  55. $obsClient -> createBucket(['Bucket' => $bucketName]);
  56. $sampleFilePath = '/temp/test.txt'; //sample large file path
  57. // you can prepare a large file in you filesystem first
  58. createSampleFile($sampleFilePath);
  59. /*
  60. * Upload an object to your source bucket
  61. */
  62. $obsClient -> putObject(['Bucket' => $sourceBucketName, 'Key' => $sourceObjectKey, 'SourceFile' => $sampleFilePath]);
  63. /*
  64. * Claim a upload id firstly
  65. */
  66. $resp = $obsClient -> initiateMultipartUpload(['Bucket' => $bucketName, 'Key' => $objectKey]);
  67. $uploadId = $resp['UploadId'];
  68. printf("Claiming a new upload id %s\n\n", $uploadId);
  69. $partSize = 5 * 1024 * 1024;
  70. $resp = $obsClient -> getObjectMetadata(['Bucket' => $sourceBucketName, 'Key' => $sourceObjectKey]);
  71. $objectSize = $resp['ContentLength'];
  72. $partCount = $objectSize % $partSize === 0 ? intval($objectSize / $partSize) : intval($objectSize / $partSize) + 1;
  73. if($partCount > 10000){
  74. throw new \RuntimeException('Total parts count should not exceed 10000');
  75. }
  76. printf("Total parts count %d\n\n", $partCount);
  77. /*
  78. * Upload multiparts by copy mode
  79. */
  80. $promise = null;
  81. $parts = [];
  82. printf("Begin to upload multiparts to OBS by copy mode\n\n");
  83. for($i = 0; $i < $partCount; $i++){
  84. $rangeStart = $i * $partSize;
  85. $rangeEnd = ($i + 1 === $partCount) ? $objectSize - 1 : $rangeStart + $partSize - 1;
  86. $partNumber = $i + 1;
  87. $p = $obsClient -> copyPartAsync([
  88. 'Bucket' => $bucketName,
  89. 'Key' => $objectKey,
  90. 'UploadId' => $uploadId,
  91. 'PartNumber' => $partNumber,
  92. 'CopySource'=>sprintf('%s/%s', $sourceBucketName, $sourceObjectKey),
  93. 'CopySourceRange' => sprintf('bytes=%d-%d', $rangeStart, $rangeEnd)
  94. ], function($exception, $resp) use (&$parts, $partNumber){
  95. $parts[] = ['PartNumber' => $partNumber, 'ETag' => $resp['ETag']];
  96. printf ( "Part#" . strval ( $partNumber ) . " done\n\n" );
  97. });
  98. if($promise === null){
  99. $promise = $p;
  100. }
  101. }
  102. /*
  103. * Waiting for all parts finished
  104. */
  105. $promise->wait();
  106. usort($parts, function($a, $b){
  107. if($a['PartNumber'] === $b['PartNumber']){
  108. return 0;
  109. }
  110. return $a['PartNumber'] > $b['PartNumber'] ? 1 : -1;
  111. });
  112. /*
  113. * Verify whether all parts are finished
  114. */
  115. if(count($parts) !== $partCount){
  116. throw new \RuntimeException('Upload multiparts fail due to some parts are not finished yet');
  117. }
  118. printf("Succeed to complete multiparts into an object named %s\n\n", $objectKey);
  119. /*
  120. * View all parts uploaded recently
  121. */
  122. printf("Listing all parts......\n");
  123. $resp = $obsClient -> listParts(['Bucket' => $bucketName, 'Key' => $objectKey, 'UploadId' => $uploadId]);
  124. foreach ($resp['Parts'] as $part)
  125. {
  126. printf("\tPart#%d, ETag=%s\n", $part['PartNumber'], $part['ETag']);
  127. }
  128. printf("\n");
  129. /*
  130. * Complete to upload multiparts
  131. */
  132. $resp = $obsClient->completeMultipartUpload([
  133. 'Bucket' => $bucketName,
  134. 'Key' => $objectKey,
  135. 'UploadId' => $uploadId,
  136. 'Parts'=> $parts
  137. ]);
  138. if(file_exists($sampleFilePath)){
  139. unlink($sampleFilePath);
  140. }
  141. } catch ( ObsException $e ) {
  142. echo 'Response Code:' . $e->getStatusCode () . PHP_EOL;
  143. echo 'Error Message:' . $e->getExceptionMessage () . PHP_EOL;
  144. echo 'Error Code:' . $e->getExceptionCode () . PHP_EOL;
  145. echo 'Request ID:' . $e->getRequestId () . PHP_EOL;
  146. echo 'Exception Type:' . $e->getExceptionType () . PHP_EOL;
  147. } finally{
  148. $obsClient->close ();
  149. }
  150. function createSampleFile($filePath)
  151. {
  152. if(file_exists($filePath)){
  153. return;
  154. }
  155. $filePath = iconv('UTF-8', 'GBK', $filePath);
  156. if(is_string($filePath) && $filePath !== '')
  157. {
  158. $fp = null;
  159. $dir = dirname($filePath);
  160. try{
  161. if(!is_dir($dir))
  162. {
  163. mkdir($dir,0755,true);
  164. }
  165. if(($fp = fopen($filePath, 'w')))
  166. {
  167. for($i=0;$i< 1000000;$i++){
  168. fwrite($fp, uniqid() . "\n");
  169. fwrite($fp, uniqid() . "\n");
  170. if($i % 100 === 0){
  171. fflush($fp);
  172. }
  173. }
  174. }
  175. }finally{
  176. if($fp){
  177. fclose($fp);
  178. }
  179. }
  180. }
  181. }