2012-12-03 77 views
10

我一直在試圖弄清楚如何從S3存儲桶中獲取內容以包含在S3存儲文件的客戶端的ZipArchive中,他們現在需要創建報告來保存被他們推到S3的文件顧客。我曾嘗試與PHP SDK 2 API(安裝了PEAR)如下:通過PHP SDK 2從S3獲取對象的內容?

require 'AWSSDKforPHP/aws.phar'; 

use Aws\S3\S3Client; 
use Aws\Common\Enum\Region; 

$config = array(
    'key' => 'the-aws-key', 
    'secret' => 'the-aws-secret', 
    'region' => Region::US_EAST_1 
); 

$aws_s3 = S3Client::factory($config); 
$app_config['s3']['bucket'] = 'the-aws-bucket'; 
$app_config['s3']['prefix'] = ''; 
$attach_name = 'hosted-test-file.jpg'; 
try { 
    $result = $aws_s3->getObject(
     array(
      'Bucket' => $app_config['s3']['bucket'], 
      'Key' => $app_config['s3']['prefix'].$attach_name 
     ) 
    ); 
    var_dump($result); 
    $body = $result->get('Body'); 
    var_dump($body); 
    $handle = fopen('php://temp', 'r'); 
    $content = stream_get_contents($handle); 
    echo "String length: ".strlen($content); 
} catch(Aws\S3\Exception\S3Exception $e) { 
    echo "Request failed.<br />"; 
} 

然而,所有的返回是一個Guzzle\Http\EntityBody對象,不知道如何抓住實際內容,所以我可以將其推入拉鍊文件。

Grabbing Object

object(Guzzle\Service\Resource\Model)[126] 
    protected 'structure' => object(Guzzle\Service\Description\Parameter)[109] 
    protected 'name' => null 
    protected 'description' => null 
    protected 'type' => string 'object' (length = 6) 
    protected 'required' => boolean false 
    protected 'enum' => null 
    protected 'additionalProperties' => boolean true 
    protected 'items' => null 
    protected 'parent' => null 
    protected 'ref' => null 
    protected 'format' => null 
    protected 'data' => array (size = 11) 
     'Body' => object(Guzzle\Http\EntityBody)[97] 
      protected 'contentEncoding' => boolean false 
      protected 'rewindFunction' => null 
      protected 'stream' => resource(292, stream) 
      protected 'size' => int 3078337 
      protected 'cache' => array (size = 9) 
      ... 
     'DeleteMarker' => string '' (length = 0) 
     'Expiration' => string '' (length = 0) 
     'WebsiteRedirectLocation' => string '' (length = 0) 
     'LastModified' => string 'Fri, 30 Nov 2012 21:07:30 GMT' (length = 29) 
     'ContentType' => string 'binary/octet-stream' (length = 19) 
     'ContentLength' => string '3078337' (length = 7) 
     'ETag' => string '"the-etag-of-the-file"' (length = 34) 
     'ServerSideEncryption' => string '' (length = 0) 
     'VersionId' => string '' (length = 0) 
     'RequestId' => string 'request-id' (length = 16) 

Returned from Body

object(Guzzle\Http\EntityBody)[96] 
    protected 'contentEncoding' => boolean false 
    protected 'rewindFunction' => null 
    protected 'stream' => resource(292, stream) 
    protected 'size' => int 3078337 
    protected 'cache' => array (size = 9) 
     'wrapper_type' => string 'php' (length = 3) 
     'stream_type' => string 'temp' (length = 4) 
     'mode' => string 'w+b' (length = 3) 
     'unread_bytes' => int 0 
     'seekable' => boolean true 
     'uri' => string 'php://temp' (length = 10) 
     'is_local' => boolean true 
     'is_readable' => boolean true 
     'is_writable' => boolean true 

// Echo of strlen() 
String length: 0 

的任何信息將會很高感激,謝謝!

解決方案

據我一段時間來弄明白,但我能找到我指出了正確的方向一個要點,以獲取該文件的內容,你需要做以下:

require 'AWSSDKforPHP/aws.phar'; 

use Aws\S3\S3Client; 
use Aws\Common\Enum\Region; 

$config = array(
    'key' => 'the-aws-key', 
    'secret' => 'the-aws-secret', 
    'region' => Region::US_EAST_1 
); 

$aws_s3 = S3Client::factory($config); 
$app_config['s3']['bucket'] = 'the-aws-bucket'; 
$app_config['s3']['prefix'] = ''; 
$attach_name = 'hosted-test-file.jpg'; 
try { 
    $result = $aws_s3->getObject(
     array(
      'Bucket' => $app_config['s3']['bucket'], 
      'Key' => $app_config['s3']['prefix'].$attach_name 
     ) 
    ); 
    $body = $result->get('Body'); 
    $body->rewind(); 
    $content = $body->read($result['ContentLength']); 
} catch(Aws\S3\Exception\S3Exception $e) { 
    echo "Request failed.<br />"; 
} 
+0

如果您確實需要從EntityBody對象中獲取底層PHP流資源,您可以使用所有'getStream()'方法。有關EntityBody對象的API文檔,請參閱http://guzzlephp.org/api/class-Guzzle.Http.EntityBody.html。 –

回答

14

響應的機身存儲在Guzzle\Http\EntityBody對象。這用於保護您的應用程序免於下載超大文件並耗盡內存。

如果您需要使用的EntityBody對象的內容作爲一個字符串,你可以投對象轉換爲字符串:

$result = $s3Client->getObject(array(
    'Bucket' => $bucket, 
    'Key' => $key 
)); 

// Cast as a string 
$bodyAsString = (string) $result['Body']; 

// or call __toString directly 
$bodyAsString = $result['Body']->__toString(); 

如果需要,您也可以直接下載到目標文件:

use Guzzle\Http\EntityBody; 

$s3Client->getObject(array(
    'Bucket' => $bucket, 
    'Key' => $key, 
    'command.response_body' => EntityBody::factory(fopen("/tmp/{$key}", 'w+')) 
)); 
0

當致電getObject時,您可以傳遞一組選項。在這些選項中,您可以指定是否要將對象下載到文件系統。

$bucket = "bucketName"; 
$file = "fileName"; 
$downloadTo = "path/to/save"; 

$opts = array( // array of options 
    'fileDownload' => $downloadTo . $file // tells the SDK to download the 
              // file to this location 
); 

$result = $aws_s3->getObject($bucket, $file, $opts); 

getObject Reference

+0

我正在使用PHP SDK 2,這是第一個SDK。相應的文檔是[here](http://docs.amazonwebservices.com/aws-sdk-php-2/latest/class-Aws.S3.S3Client.html)。 – OpensaurusRex

+1

啊,我的壞。在這種情況下忽略我的答案。與1.5的文檔相比,SDK 2的文檔可悲。 – xbonez

+0

是的,這就是爲什麼我終於決定轉向stackoverflow的答案,因爲我已經嘗試了文檔中的一切哈哈。我相信有人已經明白了。 :) – OpensaurusRex

0

我並不熟悉的版本2.00 SDK,但看起來你已經通過了流上下文上php://temp。從看你更新的問題,並從文檔的簡短一瞥,似乎流可能是可作爲:

$result = $aws_s3->getObject(
    array(
     'Bucket' => $app_config['s3']['bucket'], 
     'Key' => $app_config['s3']['prefix'].$attach_name 
    ) 
); 
$stream = $result->get('stream'); 
$content = file_get_contents($stream); 
+0

哦,那是什麼意思?讓我快速檢查它。 – OpensaurusRex

+0

我添加了更多來自對象的輸出,它看起來像試圖返回'binary/octet-stream'。 – OpensaurusRex

+0

我翻閱了更新後的問題和SDK文檔,並更新了我的答案。看起來,流處理已經可用於嵌套在其中的'Guzzle \ Service \ Resource \ Model'對象和'Guzzle \ Http \ EntityBody'對象。我的答案是從頂級對象獲取流。 –

0
<?php 
    $o_iter = $client->getIterator('ListObjects', array(
    'Bucket' => $bucketname 
    )); 
    foreach ($o_iter as $o) { 
    echo "{$o['Key']}\t{$o['Size']}\t{$o['LastModified']}\n"; 
    } 
+1

僅有代碼的答案通常不會有幫助。請解釋你在做什麼以及爲什麼。 – MattDMo

+0

這與問題無關。 – Exit