# 列举对象
![](https://support.huaweicloud.com/sdk-php-devg-obs/public_sys-resources/notice_3.0-zh-cn.png)
开发过程中，您有任何问题可以在GitHub上[提交issue](https://github.com/huaweicloud/huaweicloud-sdk-php-obs/issues)，或者在[华为云对象存储服务论坛](https://bbs.huaweicloud.com/forum/forum-620-1.html)中发帖求助。[接口参考文档](https://support.huaweicloud.com/api-obs_php_sdk_api_zh/obs_38_0001.html)详细介绍了每个接口的参数和使用方法。
您可以通过ObsClient-\>listObjects列举出桶里的对象。
该接口可设置的参数如下：
| **参数**     | **作用**                                                                                                                                                                                                                                                                     |
|:---|:---|
| Prefix   | 限定返回的对象名必须带有Prefix前缀。                                                                                                                                                                                                                                                         |
| Marker    | 列举对象的起始位置，返回的对象列表将是对象名按照字典序排序后该参数以后的所有对象。                                                                                                                                                                                                                                    |
| MaxKeys  | 列举对象的最大数目，取值范围为1\~1000，当超出范围时，按照默认的1000进行处理。                                                                                                                                                                                                                                |
| Delimiter | 用于对对象名进行分组的字符。对于对象名中包含Delimiter的对象，其对象名（如果请求中指定了Prefix，则此处的对象名需要去掉Prefix）中从首字符至第一个Delimiter之间的字符串将作为一个分组并作为CommonPrefix返回。 对于并行文件系统，不携带此参数时默认列举是递归列举此目录下所有内容，会列举子目录。在大数据场景下（目录层级深、目录下文件多）的列举，建议设置\[delimiter='/'\]，只列举当前目录下的内容，不列举子目录，提高列举效率。 |
   
#### 简单列举
以下代码展示如何简单列举对象，最多返回1000个对象：
```
<?php
// 引入依赖库
require 'vendor/autoload.php';
// 使用源码安装时引入SDK代码库
// require 'obs-autoloader.php';
// 声明命名空间
use Obs\ObsClient;
use Obs\ObsException;
// 创建ObsClient实例
$obsClient = new ObsClient([
    //推荐通过环境变量获取访问密钥AK/SK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险。
    //您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
    'key' => getenv('ACCESS_KEY_ID'),
    'secret' => getenv('SECRET_ACCESS_KEY'),
    'endpoint' => 'https://your-endpoint',
    'signature' => 'obs'
]);
// 列举桶内对象
try {
    $resp = $obsClient->listObjects([
        'Bucket' => 'bucketname'
    ]);
    printf( "RequestId:%s\n", $resp['RequestId']);
    foreach ($resp['Contents'] as $index => $content) {
        printf( "Contents[%d]\n", $index + 1 );
        printf( "Key:%s\n", $content['Key']);
        printf( "LastModified:%s\n", $content['LastModified']);
        printf( "ETag:%s\n", $content['ETag']);
        printf( "Size:%s\n", $content['Size']);
        printf( "Owner[ID]:%s\n", $content['Owner']['ID']);}
} catch (ObsException $e) {
    // 操作失败，获取详细异常信息
    printf("ListObjectsFailed: Status:%d, Code:%s, Message:%s\n",
        $e->getStatusCode(), $e->getExceptionCode(), $e->getExceptionMessage());
} finally {
    // 关闭ObsClient，释放资源
    $obsClient->close();
}
```
![](https://support.huaweicloud.com/sdk-php-devg-obs/public_sys-resources/note_3.0-zh-cn.png)
- 每次至多返回1000个对象，如果指定桶包含的对象数量大于1000，则返回结果中IsTruncated为true表明本次没有返回全部对象，并可通过NextMarker获取下次列举的起始位置。
- 如果想获取指定桶包含的所有对象，可以采用分页列举的方式。
 
#### 指定数目列举
以下代码展示如何指定数目列举对象：
```
<?php
// 引入依赖库
require 'vendor/autoload.php';
// 使用源码安装时引入SDK代码库
// require 'obs-autoloader.php';
// 声明命名空间
use Obs\ObsClient;
use Obs\ObsException;
// 创建ObsClient实例
$obsClient = new ObsClient([
    //推荐通过环境变量获取访问密钥AK/SK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险。
    //您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
    'key' => getenv('ACCESS_KEY_ID'),
    'secret' => getenv('SECRET_ACCESS_KEY'),
    'endpoint' => 'https://your-endpoint',
    'signature' => 'obs'
]);
// 列举桶内对象
try {
    $resp = $obsClient->listObjects([
        'Bucket' => 'bucketname',
        // 列举100个对象
        'MaxKeys' => 100
    ]);
    printf( "RequestId:%s\n", $resp['RequestId']);
    foreach ($resp['Contents'] as $index => $content) {
        printf( "Contents[%d]\n", $index + 1 );
        printf( "Key:%s\n", $content['Key']);
        printf( "LastModified:%s\n", $content['LastModified']);
        printf( "ETag:%s\n", $content['ETag']);
        printf( "Size:%s\n", $content['Size']);
        printf( "Owner[ID]:%s\n", $content['Owner']['ID']);}
} catch (ObsException $e) {
    // 操作失败，获取详细异常信息
    printf("ListObjectsFailed: Status:%d, Code:%s, Message:%s\n",
        $e->getStatusCode(), $e->getExceptionCode(), $e->getExceptionMessage());
} finally {
    // 关闭ObsClient，释放资源
    $obsClient->close();
}
```
#### 指定前缀列举
以下代码展示如何指定前缀列举对象：
```
<?php
// 引入依赖库
require 'vendor/autoload.php';
// 使用源码安装时引入SDK代码库
// require 'obs-autoloader.php';
// 声明命名空间
use Obs\ObsClient;
use Obs\ObsException;
// 创建ObsClient实例
$obsClient = new ObsClient([
    //推荐通过环境变量获取访问密钥AK/SK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险。
    //您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
    'key' => getenv('ACCESS_KEY_ID'),
    'secret' => getenv('SECRET_ACCESS_KEY'),
    'endpoint' => 'https://your-endpoint',
    'signature' => 'obs'
]);
// 列举桶内对象
try {
    $resp = $obsClient->listObjects([
        'Bucket' => 'bucketname',
        // 设置列举带有prefix前缀的100个对象
        'MaxKeys' => 100,
        'Prefix' => 'prefix'
    ]);
    printf( "RequestId:%s\n", $resp['RequestId']);
    foreach ($resp['Contents'] as $index => $content) {
        printf( "Contents[%d]\n", $index + 1 );
        printf( "Key:%s\n", $content['Key']);
        printf( "LastModified:%s\n", $content['LastModified']);
        printf( "ETag:%s\n", $content['ETag']);
        printf( "Size:%s\n", $content['Size']);
        printf( "Owner[ID]:%s\n", $content['Owner']['ID']);}
} catch (ObsException $e) {
    // 操作失败，获取详细异常信息
    printf("ListObjectsFailed: Status:%d, Code:%s, Message:%s\n",
        $e->getStatusCode(), $e->getExceptionCode(), $e->getExceptionMessage());
} finally {
    // 关闭ObsClient，释放资源
    $obsClient->close();
}
```
#### 指定起始位置列举
以下代码展示如何指定起始位置列举对象：
```
<?php
// 引入依赖库
require 'vendor/autoload.php';
// 使用源码安装时引入SDK代码库
// require 'obs-autoloader.php';
// 声明命名空间
use Obs\ObsClient;
use Obs\ObsException;
// 创建ObsClient实例
$obsClient = new ObsClient([
    //推荐通过环境变量获取访问密钥AK/SK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险。
    //您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
    'key' => getenv('ACCESS_KEY_ID'),
    'secret' => getenv('SECRET_ACCESS_KEY'),
    'endpoint' => 'https://your-endpoint',
    'signature' => 'obs'
]);
// 列举桶内对象
try {
    $resp = $obsClient->listObjects([
        'Bucket' => 'bucketname',
        // 设置列举对象名字典序在"test"之后的100个对象
        'MaxKeys' => 100,
        'Marker' => 'test'
    ]);
    printf( "RequestId:%s\n", $resp['RequestId']);
    foreach ($resp['Contents'] as $index => $content) {
        printf( "Contents[%d]\n", $index + 1 );
        printf( "Key:%s\n", $content['Key']);
        printf( "LastModified:%s\n", $content['LastModified']);
        printf( "ETag:%s\n", $content['ETag']);
        printf( "Size:%s\n", $content['Size']);
        printf( "Owner[ID]:%s\n", $content['Owner']['ID']);}
} catch (ObsException $e) {
    // 操作失败，获取详细异常信息
    printf("ListObjectsFailed: Status:%d, Code:%s, Message:%s\n",
        $e->getStatusCode(), $e->getExceptionCode(), $e->getExceptionMessage());
} finally {
    // 关闭ObsClient，释放资源
    $obsClient->close();
}
```
#### 分页列举全部对象
以下代码展示分页列举全部对象：
```
<?php
// 引入依赖库
require 'vendor/autoload.php';
// 使用源码安装时引入SDK代码库
// require 'obs-autoloader.php';
// 声明命名空间
use Obs\ObsClient;
use Obs\ObsException;
// 创建ObsClient实例
$obsClient = new ObsClient([
    //推荐通过环境变量获取访问密钥AK/SK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险。
    //您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
    'key' => getenv('ACCESS_KEY_ID'),
    'secret' => getenv('SECRET_ACCESS_KEY'),
    'endpoint' => 'https://your-endpoint',
    'signature' => 'obs'
]);
// 列举桶内对象
try {
    $marker = null;
    $index = 1;
    $isTruncated = true;
    while ($isTruncated) {
        $resp = $obsClient->listObjects([
            'Bucket' => 'bucketname',
            // 设置每页100个对象
            'MaxKeys' => 100,
            'Marker' => $marker
        ]);
    printf( "RequestId:%s\n", $resp['RequestId']);
    foreach ($resp['Contents'] as $content) {
        printf( "Contents[%d]\n", $index );
        printf( "Key:%s\n", $content['Key']);
        printf( "LastModified:%s\n", $content['LastModified']);
        printf( "ETag:%s\n", $content['ETag']);
        printf( "Size:%s\n", $content['Size']);
        printf( "Owner[ID]:%s\n", $content['Owner']['ID']);
        printf("StorageClass:%s\n", $content['StorageClass']);
        $index ++;
    }
    $isTruncated = $resp['IsTruncated'];
    $marker = $resp['NextMarker'];
    // NextMarker 空值保护：IsTruncated 为 true 但 NextMarker 为空时停止，避免死循环
    if ($isTruncated && $marker === null) {
        printf("Warning: IsTruncated is true but NextMarker is null, stop pagination.\n");
        break;
    }
    }
} catch (ObsException $e) {
    // 操作失败，获取详细异常信息
    printf("ListObjectsFailed: Status:%d, Code:%s, Message:%s\n",
        $e->getStatusCode(), $e->getExceptionCode(), $e->getExceptionMessage());
} finally {
    // 关闭ObsClient，释放资源
    $obsClient->close();
}
```
#### 列举文件夹中的所有对象
OBS本身是没有文件夹的概念的，桶中存储的元素只有对象。文件夹对象实际上是一个大小为0且对象名以"/"结尾的对象，将这个文件夹对象名作为前缀，即可模拟列举文件夹中对象的功能。以下代码展示如何列举文件夹中的对象：
```
<?php
// 引入依赖库
require 'vendor/autoload.php';
// 使用源码安装时引入SDK代码库
// require 'obs-autoloader.php';
// 声明命名空间
use Obs\ObsClient;
use Obs\ObsException;
// 创建ObsClient实例
$obsClient = new ObsClient([
    //推荐通过环境变量获取访问密钥AK/SK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险。
    //您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
    'key' => getenv('ACCESS_KEY_ID'),
    'secret' => getenv('SECRET_ACCESS_KEY'),
    'endpoint' => 'https://your-endpoint',
    'signature' => 'obs'
]);
// 列举桶内对象
try {
    $marker = null;
    $index = 1;
    $isTruncated = true;
    while ($isTruncated) {
        $resp = $obsClient->listObjects([
            'Bucket' => 'bucketname',
            'MaxKeys' => 1000,
            // 设置文件夹对象名"dir/"为前缀
            'Prefix' => 'dir/',
            'Marker' => $marker
        ]);
    printf( "RequestId:%s\n", $resp['RequestId']);
    foreach ($resp['Contents'] as $content) {
        printf( "Contents[%d]\n", $index );
        printf( "Key:%s\n", $content['Key']);
        printf( "LastModified:%s\n", $content['LastModified']);
        printf( "ETag:%s\n", $content['ETag']);
        printf( "Size:%s\n", $content['Size']);
        printf( "Owner[ID]:%s\n", $content['Owner']['ID']);
        printf("StorageClass:%s\n", $content['StorageClass']);
        $index ++;
    }
    $isTruncated = $resp['IsTruncated'];
    $marker = $resp['NextMarker'];
    // NextMarker 空值保护：IsTruncated 为 true 但 NextMarker 为空时停止，避免死循环
    if ($isTruncated && $marker === null) {
        printf("Warning: IsTruncated is true but NextMarker is null, stop pagination.\n");
        break;
    }
    }
} catch (ObsException $e) {
    // 操作失败，获取详细异常信息
    printf("ListObjectsFailed: Status:%d, Code:%s, Message:%s\n",
        $e->getStatusCode(), $e->getExceptionCode(), $e->getExceptionMessage());
} finally {
    // 关闭ObsClient，释放资源
    $obsClient->close();
}
```
#### 按文件夹分组列举所有对象
以下代码展示如何按文件夹分组，列举桶内所有对象：
```
<?php
// 引入依赖库
require 'vendor/autoload.php';
// 使用源码安装时引入SDK代码库
// require 'obs-autoloader.php';
// 声明命名空间
use Obs\ObsClient;
use Obs\ObsException;
// 创建ObsClient实例
$obsClient = new ObsClient([
    //推荐通过环境变量获取访问密钥AK/SK，这里也可以使用其他外部引入方式传入，如果使用硬编码可能会存在泄露风险。
    //您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
    'key' => getenv('ACCESS_KEY_ID'),
    'secret' => getenv('SECRET_ACCESS_KEY'),
    'endpoint' => 'https://your-endpoint',
    'signature' => 'obs'
]);
// 列举桶内对象
try {
    function listObjectsByPrefix($commonPrefixes, $obsClient, $depth = 0, $maxDepth = 20){
        if ($depth >= $maxDepth) {
            printf("Reached max recursion depth %d, stop recursing.\n", $maxDepth);
            return;
        }
    foreach ($commonPrefixes as $commonPrefix){
        $resp = $obsClient->listObjects([
            'Bucket' => 'bucketname',
            // 设置文件夹分隔符"/"
            'Delimiter' => '/',
            'Prefix' => $commonPrefix['Prefix']
        ]);
    printf("Objects in folder [%s]:\n", $commonPrefix['Prefix']);
    foreach ($resp['Contents'] as $index => $content) {
        printf( "Contents[%d]\n", $index );
        printf( "Key:%s\n", $content['Key']);
        printf( "LastModified:%s\n", $content['LastModified']);
        printf( "ETag:%s\n", $content['ETag']);
        printf( "Size:%s\n", $content['Size']);
        printf( "Owner[ID]:%s\n", $content['Owner']['ID']);
        printf("StorageClass:%s\n", $content['StorageClass']);
    }
    printf("\n");
    listObjectsByPrefix($resp['CommonPrefixes'], $obsClient, $depth + 1, $maxDepth);
    }
    }
    $resp = $obsClient->listObjects([
        'Bucket' => 'bucketname',
        // 设置文件夹分隔符"/"
        'Delimiter' => '/'
    ]);printf( "Objects in the root directory:\n");
    foreach ($resp['Contents'] as $index => $content) {
        printf("Contents[%d]\n", $index );
        printf("Key:%s\n", $content['Key']);
        printf("LastModified:%s\n", $content['LastModified']);
        printf("ETag:%s\n", $content['ETag']);
        printf("Size:%s\n", $content['Size']);
        printf("Owner[ID]:%s\n", $content['Owner']['ID']);
        printf("\n");
        listObjectsByPrefix($resp['CommonPrefixes'], $obsClient);
    }
} catch (ObsException $e) {
    // 操作失败，获取详细异常信息
    printf("ListObjectsFailed: Status:%d, Code:%s, Message:%s\n",
        $e->getStatusCode(), $e->getExceptionCode(), $e->getExceptionMessage());
} finally {
    // 关闭ObsClient，释放资源
    $obsClient->close();
}
```
![](https://support.huaweicloud.com/sdk-php-devg-obs/public_sys-resources/note_3.0-zh-cn.png)
- 以上代码示例没有考虑文件夹中对象数超过1000个的情况。
- 由于是需要列举出文件夹中的对象和子文件夹，且文件夹对象总是以"/"结尾，因此Delimiter总是为"/"。
- 每次递归的返回结果中Contents包含的是文件夹中的对象；CommonPrefixes包含的是文件夹的子文件夹。
 
