2012-12-03 7 views
10

Ho cercato di capire come prelevare il contenuto da un bucket S3 da includere in un ZipArchive per un client che sta memorizzando i file su S3, ora devono creare report che contengano i file che sono stati inseriti in S3 dal loro clienti. Ho provato quanto segue con il 2 API PHP SDK (installato con PEAR):Acquisizione del contenuto di Object da S3 tramite PHP SDK 2?

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 />"; 
} 

Tuttavia, tutto restituisce è un oggetto Guzzle\Http\EntityBody, non sicuro come per afferrare il contenuto effettivo così posso spingerlo nella zip file.

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 

Qualsiasi informazione sarebbe elevato apprezzato, grazie!

Soluzione

Mi fa un po 'per capirlo, ma sono stato in grado di trovare una sostanza che mi ha segnalato nella giusta direzione, al fine di ottenere il contenuto del file è necessario eseguire le seguenti operazioni :

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

Se è davvero necessario afferrare la risorsa di flusso PHP sottostante da un oggetto EntityBody, è possibile utilizzare il metodo 'getStream()'. Vedi http://guzzlephp.org/api/class-Guzzle.Http.EntityBody.html per la documentazione API dell'oggetto EntityBody. –

risposta

14

Il corpo della risposta è memorizzato in un oggetto Guzzle\Http\EntityBody. Questo è usato per proteggere la tua applicazione dal download di file estremamente grandi e dalla mancanza di memoria.

Se è necessario utilizzare il contenuto del dell'oggetto EntityBody come una stringa, si può lanciare l'oggetto in una stringa:

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

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

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

È possibile anche scaricare direttamente nel file di destinazione, se necessario:

use Guzzle\Http\EntityBody; 

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

Quando si chiama getObject, è possibile passare in una serie di opzioni. In queste opzioni, è possibile specificare se si desidera scaricare l'oggetto nel proprio file system.

$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

Sto usando il PHP SDK 2, che è il primo SDK. I documenti appropriati sono [qui] (http://docs.amazonwebservices.com/aws-sdk-php-2/latest/class-Aws.S3.S3Client.html). – OpensaurusRex

+1

Ah, mio ​​male. Ignora la mia risposta in quel caso. I documenti dell'SDK 2 sono purtroppo carenti rispetto ai documenti dell'1.5. – xbonez

+0

Sì, ecco perché alla fine ho deciso di passare allo stackoverflow per la risposta poiché ho provato tutto nella documentazione lol. Sono sicuro che qualcuno l'ha capito. :) – OpensaurusRex

0

Io non sono che la familiarità con la versione 2.00 SDK, ma sembra che v'è stato superato un contesto torrente su php://temp. Guardando la tua domanda aggiornato e da un breve sguardo alla documentazione, sembra che la corrente può essere disponibile come:

$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

Oh, questo significava? Fammi controllare molto velocemente. – OpensaurusRex

+0

Ho aggiunto più output degli oggetti, sembra che stia cercando di restituire 'binary/octet-stream'. – OpensaurusRex

+0

Ho controllato la tua domanda aggiornata e la documentazione SDK e ho aggiornato la mia risposta. Sembra che l'handle del flusso sia già disponibile sia sull'oggetto 'Guzzle \ Service \ Resource \ Model' che sull'oggetto' Guzzle \ Http \ EntityBody' all'interno di esso. La mia risposta è solo ottenere il flusso dall'oggetto di livello superiore. –

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

Le risposte solo in codice non sono generalmente utili. Per favore, spiega cosa stai facendo e perché. – MattDMo

+0

Questo non ha nulla a che fare con la domanda posta. – Exit

Problemi correlati