S3にファイルを保存しているクライアントのZipArchiveに含めるためにS3バケットからコンテンツを取得する方法を見つけようとしていましたが、顧客によってS3にプッシュされたファイルを保持するレポートを作成する必要があります。 PHP SDK 2 API(PEARと共にインストール))で以下を試しました。
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
オブジェクト、実際のコンテンツを取得する方法がわからないため、Zipファイルにプッシュできます。
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)
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 />";
}
応答の本文は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+'))
));
これは私のために働いた:
$tempSave = 'path/to/save/filename.txt';
return $this->S3->getObject([
'Bucket' => 'test',
'Key' => $keyName,
'SaveAs' => $tempSave,
]);
私はバージョン2.00SDKにあまり詳しくありませんが、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);
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);
<?php
$o_iter = $client->getIterator('ListObjects', array(
'Bucket' => $bucketname
));
foreach ($o_iter as $o) {
echo "{$o['Key']}\t{$o['Size']}\t{$o['LastModified']}\n";
}