2

多くの画像を S3 バケットにアップロードしようとしています。速度を念頭に置いて、データをメモリに保持することで、ディスクの読み取りと書き込みの回数を減らしたいと考えています。この目的のために、次のスキームを考え出しました。

//fetch binary image data from remote URL
$contents = file_get_contents("http://somesite.com/image.jpg");
//trim the image as per: http://stackoverflow.com/a/15104071/568884
$out = shell_exec('echo ' . base64_encode($contents) . " | base64 -d | convert - -fuzz 10% -trim jpeg:-");
//create a temporary resource to pass to S3's inputResource() method.
$resource = fopen('php://temp', 'r+');
//write the binary data into the empty resource.
fwrite($resource, $out);
//pass the resource and length of binary data into inputResource()
$ir = $this->s3->inputResource($resource, strlen($out));
//finally transfer the resource from machine to S3.
$this->s3->putObject($ir, $bucket, $s3_path, S3::ACL_PUBLIC_READ);

エラーは次のとおりです: S3::putObject(): [RequestTimeout] サーバーへのソケット接続は、タイムアウト期間内に読み書きされませんでした。アイドル状態の接続は閉じられ、データは S3 に書き込まれません。

$out の割り当てを単に空の文字列に置き換えると$out = "";、ライブラリは期待どおりに 0 バイトのファイルを S3 に正常に書き込みます。

私はCodeIgniter S3ライブラリを使用しています...これはAWS S3 API afaikの単なるラッパーです。

4

2 に答える 2

1

ファイルハンドル$resourceをライブラリに渡していますが、ファイルポインタがファイルの最後になるように最初にライブラリに書き込んでいます。

ライブラリはおそらくそのエッジケースを処理できません(ソースコードはそれを示唆しています)。

rewind($resource)ファイルに書き込んだ後、S3 ライブラリに渡す前に、ファイルを試すことができます。

これを少し高速化したい場合は、必要に応じて PHP に小さなファイル用のメモリを使用させることができphp://tempます php://memory。詳細とオプションについてはphp://ラッパーのドキュメントを参照してください。

S3ライブラリところで。公式のものではありません。通知と警告を有効にすると、まだ PHP 4 コードが含まれているため、いくつかの問題が報告される可能性があります。

于 2013-03-10T12:21:05.560 に答える
0

RequestTimeout エラーの考えられる原因は、putObject への呼び出しが、送信される実際のデータとは異なる Content-Length を指定している可能性があります。AWS フォーラムの Amazon 担当者によると:

RequestTimeout エラーをトリガーする 1 つの方法は、Content-Length を 2 に指定し、要求本文に 1 バイトのオブジェクト データのみを含む PUT 要求を送信することです。残りのバイトが到着するまで 20 秒待った後、Amazon S3 は RequestTimeour エラーで応答します。

そのため、strlen() 関数を使用すると、一時ファイルが間違った長さを報告し、この間違った値が原因で S3 が例外で応答する可能性があります。

strlen()のphpドキュメントに関するコメントによると、関数は文字列が常にASCIIであると想定しているため、ファイル内の間違ったバイト数を報告する可能性があります:

その場合、バイナリ データを unocode 文字列として扱い、間違った値を返す可能性があります。

strlen() をmb_strlen()の呼び出しに置き換えてみてください。常に正しいバイト数が報告されるはずです。

于 2013-03-05T10:34:02.863 に答える