2016-12-13 50 views
1

ファイルを受信して​​います(最大4 GB):ファイルコンテンツがPOSTリクエストの本体で私にストリーミングされています。 このストリームをローカルにまず保存せずに、s3バケットに直接アップロードしたいとします。 さまざまな理由で既に失敗したさまざまなアプローチを試しました。S3:putObject()POST経由で受信するストリーム

私の現在のアプローチ:

use GuzzleHttp\Psr7\Stream; 
use Aws\S3\S3Client; 

$s3 = new \Aws\S3\S3Client([ 
    'version' => 'latest', 
    'region' => 'eu-west-1', 
    'credentials' => [ 
     'key' => 'abc', 
     'secret' => '123' 
    ] 
]); 

$stream = new \GuzzleHttp\Psr7\Stream(fopen('php://input', 'r')); 

$result = $s3->putObject(array(
    'Bucket' => $bucket, 
    'Key' => $keyname, 
    'ContentLength' => (int)$_SERVER['CONTENT_LENGTH'], 
    'Body' => $stream->getContents(), 
    'ACL' => 'private', 
    'StorageClass' => 'STANDARD_IA', 
)); 

80メガバイトのファイルストリーミングしようとしているときに次のエラーが発生します。Stream.phpの

PHP message: PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 78847383 bytes) in /var/www/slimapi/vendor/slim/slim/Slim/Http/Stream.php on line 403 

ライン403は次のとおりです。

if (!$this->isReadable() || ($contents = stream_get_contents($this->stream)) === false) { 

したがって、おそらくエラーは、ストリームの内容全体を文字列にロードすることによってトリガーされます。メモリの制限。 (エラーがスリム/ストリーム内で発生している理由は、私は\ストリームをがつがつ食う使用しようとしているとしてそれは、刺激です)

だから私の質問は以下のとおりです。 どうやってなくてS3バケットに直接入ってくるPOSTデータをストリームすることができますメモリの問題につながるバッファリングの問題?

私はすでに試した:

  • $ストリーム= Psr7の\ stream_for(のfopen( 'PHP://入力'、 'R'));
  • $ stream = fopen( 'php:// input'、 'r'); PHP SDKの呼び出しが読んで直接サポートしていないこと、
+0

私たちが提供しているさまざまなアプローチを示すのに役立ちます。 –

答えて

0

のputObject内

  • (): 'ボディ' =>ストリーム::工場( 'R')のfopen( '//入力PHP')ストリーム。だから私には起こっているように見えるのは、実際にはSDKにオブジェクトのデータ列を渡すために実際に呼び出す前に、オブジェクトがストリームから変数にオブジェクト全体を読み込むときに、PHPがメモリを消費しているということです。

    S3 Stream Wrapperを使用することを検討してください。

    この例は最も適切なようですが、両方のストリーム間でデータを渡す必要があります。 S3 Stream Wrapperはローカルファイルからのストリームの作成をサポートしているように見えますが、既存のストリームをストリームに渡すという直接的な例はありませんでした。

    この例では、使用可能な場合は4096バイトを読み込みます(4096が使用できない場合はそれより少なく、戻り値が空でない場合はS3オブジェクトに書き込みます)。ソースはEOFに達しました(この例ではソースはEOFに対応しています)。

    $client = new Aws\S3\S3Client([/** options **/]); 
    
    // Register the stream wrapper from an S3Client object 
    $client->registerStreamWrapper(); 
    
    $stream = fopen('s3://bucket/key', 'w'); 
    while (!$stream_source->stream_eof()) { 
        $string = $stream_source->stream_read (4096) 
        if (!empty($string)) { 
         fwrite($stream, $string); 
        } 
    } 
    fclose($stream); 
    
  • 関連する問題