循环访问 Amazon S3 上文件夹中的对象


Iterating over the objects in a folder on amazon S3

我们有一个应用程序,用户可以在其中创建自己的网页并托管它们。我们使用 S3 来存储页面,因为它们是静态的。在这里,由于我们限制每个用户 100 个存储桶,我们决定在存储桶内为每个用户使用文件夹。

现在,如果用户想在他的域上托管他的网站,我们会要求他提供域名(当他开始时,我们将其发布在我们的子域上),我必须重命名文件夹。

S3 是一个平面文件系统,我知道实际上没有文件夹,而只是分隔值/分量表,所以我无法进入文件夹并检查它包含多少页。API 允许一个接一个,但为此我们必须知道存储桶中的对象名称。

浏览了文档并遇到了我尚未实现的迭代器。这使用我没有经验的消耗,并且在实施
时面临挑战

我能走哪条路,或者我需要走这条路。

您可以通过执行以下操作为"文件夹"的内容创建迭代器:

$objects = $s3->getIterator('ListObjects', array(
    'Bucket'    => 'bucket-name',
    'Prefix'    => 'subfolder-name/',
    'Delimiter' => '/',
));
foreach ($objects as $object) {
    // Do things with each object
}

如果你只需要一个计数,你可以这样:

echo iterator_count($s3->getIterator('ListObjects', array(
    'Bucket'    => 'bucket-name',
    'Prefix'    => 'subfolder-name/',
    'Delimiter' => '/',
)));

s3 的学习曲线有点,嗯?我花了大约 2 个小时,最终得到了这个编码点火器解决方案。我编写了一个控制器来循环访问我的已知子文件夹。

function s3GetObjects($bucket) {
    $CI =& get_instance();
    $CI->load->library('aws_s3');
    $prefix = $bucket.'/';
    $objects = $CI->aws_s3->getIterator('ListObjects', array(
        'Bucket'    => $CI->config->item('s3_bucket'),
        'Prefix'    => $prefix,
        'Delimiter' => '/',
    ));
    foreach ($objects as $object) {
        if ($object['Key'] == $prefix) continue;
        echo $object['Key'].PHP_EOL;
        if (!file_exists(FCPATH.$object['Key'])) {
            try {
                $r = $CI->aws_s3->getObject(array(
                    'Bucket' => $CI->config->item('s3_bucket'),
                    'Key'    => $object['Key'],
                    'SaveAs' => FCPATH.$object['Key']
                ));
            } catch (Exception $e) {
                echo $e->getMessage().PHP_EOL;
                //return FALSE;
            }
            echo PHP_EOL;
        } else {
            echo ' -- file exists'.PHP_EOL;
        }
    }
    return TRUE;
}