6

Amazon S3 のバケットからファイルを一覧表示し、それらの各ファイルのメタデータを抽出するより効率的な方法はありますか? AWS PHP SDK を使用しています。

if ($paths = $s3->get_object_list('my-bucket')) {
    foreach($paths AS $path) {
        $meta = $s3->get_object_metadata('my-bucket', $path);
        echo $path . ' was modified on ' . $meta['LastModified'] . '<br />';
    }
}

現時点では、get_object_list()を実行してすべてのファイルを一覧表示し、次に各ファイルに対してget_object_metadata()を実行してメタ データを取得する必要があります。

バケットに 100 個のファイルがある場合、このデータを取得するために 101 回の呼び出しが行われます。1回の通話で出来れば良いのですが。

例えば:

if ($paths = $s3->get_object_list('my-bucket')) {
    foreach($paths AS $path) {
        echo $path['FileName'] . ' was modified on ' . $path['LastModified'] . '<br />';
    }
}
4

3 に答える 3

3

これは少し古いことは知っていますが、この問題が発生したため、このタイプの問題にバッチ機能を使用するようにAwsSDKを拡張しました。これにより、多くのファイルのカスタムメタデータをすばやく取得できます。これは私のコードです:

    /**
     * Name: Steves_Amazon_S3
     * 
     * Extends the AmazonS3 class in order to create a function to 
     * more efficiently retrieve a list of
     * files and their custom metadata using the CFBatchRequest function.
     * 
     * 
     */
    class Steves_Amazon_S3 extends AmazonS3 {

        public function get_object_metadata_batch($bucket, $filenames, $opt = null) {
            $batch = new CFBatchRequest();

            foreach ($filenames as $filename) {

                $this->batch($batch)->get_object_headers($bucket, $filename); // Get content-type
            }

            $response = $this->batch($batch)->send();

            // Fail if any requests were unsuccessful
            if (!$response->areOK()) {
                return false;
            }
            foreach ($response as $file) {
                $temp = array();
                $temp['name'] = (string) basename($file->header['_info']['url']);
                $temp['etag'] = (string) basename($file->header['etag']);
                $temp['size'] = $this->util->size_readable((integer) basename($file->header['content-length']));
                $temp['size_raw'] = basename($file->header['content-length']);
                $temp['last_modified'] = (string) date("jS M Y H:i:s", strtotime($file->header['last-modified']));
                $temp['last_modified_raw'] = strtotime($file->header['last-modified']);
                @$temp['creator_id'] = (string) $file->header['x-amz-meta-creator'];
                @$temp['client_view'] = (string) $file->header['x-amz-meta-client-view'];
                @$temp['user_view'] = (string) $file->header['x-amz-meta-user-view'];

                $result[] = $temp;
            }

            return $result;
        }
    }
于 2012-09-04T14:28:34.197 に答える
2

list_objects機能には限界があることを知っておく必要があります。max-keysオプションが大きな数に設定されていても、1000 を超えるオブジェクトをロードすることはできません。

これを修正するには、データを数回ロードする必要があります。

private function _getBucketObjects($prefix = '', $booOneLevelOny = false)
{
    $objects = array();
    $lastKey = null;
    do {
        $args = array();
        if (isset($lastKey)) {
            $args['marker'] = $lastKey;
        }

        if (strlen($prefix)) {
            $args['prefix'] = $prefix;
        }

        if($booOneLevelOny) {
            $args['delimiter'] = '/';
        }

        $res = $this->_client->list_objects($this->_bucket, $args);
        if (!$res->isOK()) {
            return null;
        }

        foreach ($res->body->Contents as $object) {
            $objects[] = $object;
            $lastKey = (string)$object->Key;
        }
        $isTruncated = (string)$res->body->IsTruncated;
        unset($res);
    } while ($isTruncated == 'true');

    return $objects;
}

その結果、オブジェクトの完全なリストが得られます。


カスタムヘッダーがある場合はどうなりますか? それらは関数経由では返されませんlist_objects。この場合、これが役立ちます:

foreach (array_chunk($arrObjects, 1000) as $object_set) {
    $batch = new CFBatchRequest();
    foreach ($object_set as $object) {
        if(!$this->isFolder((string)$object->Key)) {
            $this->_client->batch($batch)->get_object_headers($this->_bucket, $this->preparePath((string)$object->Key));
        }
    }

    $response = $this->_client->batch($batch)->send();

    if ($response->areOK()) {
        foreach ($response as $arrHeaderInfo) {
            $arrHeaders[] = $arrHeaderInfo->header;
        }
    }
    unset($batch, $response);
}
于 2012-12-21T10:15:29.340 に答える
0

必要な LastModified メタを引き出すlist_objects関数を使用することになりました。

1回の通話ですべて:)

于 2012-06-20T04:49:48.940 に答える