对象存储 PHP SDK
安装
SDK
GitHub 地址: https://github.com/NetEase-Object-Storage/nos-php-sdk
ChangLog: https://github.com/NetEase-Object-Storage/nos-php-sdk/blob/master/README.md
历史版本: 无
环境要求
php5.3+ 使用以下命令显示当前的 php 版本:
php -v
cURL 扩展 使用以下命令查看 curl 扩展是否已经安装好:
php -m
Windows下用户,请参考 Windows下使用NOS PHP SDK
安装
composer方式
如果您通过 composer 管理您的项目依赖,可以在你的项目根目录运行:
composer require netease/nos-php-sdk
或者在你的 composer.json 中声明对 NOS SDK for PHP 的依赖:
"require": { "netease/nos-php-sdk": "1.0.0" }
然后通过 conposer install 安装依赖,安装完成后形成如下目录结构:
. ├── app.php ├── composer.json ├── composer.lock └── vendor
其中 app.php 是用户的应用程序,vendor/ 目录下包含了所依赖的库,用户需要在 app.php 中引入如下依赖:
require_once __DIR__ . '/vendor/autoload.php';
1. 如果项目中已经引用过 autoload.php,则加入了 sdk 依赖之后,不需要再引入 autoload.php 了
2. 如果使用 composer 出现网络错误,可以使用 composer 中国区的镜像源,方法是在命令行执行: composer config -g repositories.packagist composer https://packagist.phpcomposer.com
phar 方式
使用 phar 单文件方式,可以在以下 链接,下载已经打好包的 phar 文件,或者根据源文件自行编译,然后在你的源代码中引入 phar 文件:
require_once '/path/to/nos-sdk-php.phar';
源码方式
使用 SDK 源码,在发布页面,选择相应的版本,下载打好包的 zip 文件,解压后的根目录中包含一个 autoload.php 文件,在您的代码中引入这个文件:require_once '/path/to/nos-sdk/autoload.php';
运行 Samples
- 解压下载到的 sdk 包
- 修改samples目录中的 Config.php 文件
1. 修改 NOS_ACCESS_ID, 您从 NOS 获得的AccessKeyId
2. 修改 NOS_ACCESS_KEY, 您从 NOS 获得的AccessKeySecret
3. 修改 NOS_ENDPOINT, 您选定的 NOS 数据中心访问域名,例如: nos-eastchina1.126.net
4. 修改 NOS_TEST_BUCKET, 您要用来运行 sample 使用的 bucket,sample 程序会在这个bucket中创建一些文件,注意不能用生产环境的 bucket,以 免污染用户数据
- 到 samples 目录中执行 php RunAll.php, 也可以单个运行某个 Sample 文件
初始化
确定 EndPoint
EndPoint 是 NOS 各个区域的地址,目前支持以下形式
EndPoint 类型 | 备注 |
---|---|
NOS区域域名地址 | 使用桶所在的区域的NOS域名地址 |
NOS 区域域名地址
进入 NOS 控制台,在桶的属性中可以查找到当前桶所在的区域及域名,桶的域名的后缀部分为 该桶的公网域名,例如: test-logging.nos-eastchina1.126.net 中的 nos-eastchina1.126.net 为该桶的公网 EndPoint 。
配置秘钥
要接入 NOS 服务,您需要一对有效的 AccessKey(包括 AccessKeyId 与 AccessKeySecret)来进行 签名验证,开通服务与 AccessKey 请参考 访问控制
在获取到 AccessKeyId 与 AccessKeySecret 之后,可以按照以下的步骤进行初始化
新建 NosClient
使用 NOS 地区域名创建 NosClient
初始化代码如下所示:
<?php use NOS\NosClient; use NOS\Core\NosException; $accessKeyId = "您的accessKeyId"; $accessKeySecret = "您的accessKeySecret"; $endPoint = "建桶时选择的的区域域名"; try{ $nosClient = new NosClient($accessKeyId,$accessKeySecret,$endPoint); } catch(NosException e){ print e->getMessage(); }
设置网络参数
我们可以通过 Client 设置一些基本的网络参数:
<?php $nosClient->setTimeout(3600 /* seconds */); $nosClient->setConnectTimeout(10 /* seconds */);
其中:
- setTimeout 设置请求超时时间,单位秒,默认是 5184000 秒, 这里建议不要设置太小,如果上传文件很大,消耗的时间会比较长
- setConnectTimeout 设置连接超时时间,单位秒,默认是10秒
快速入门
请确认您已经熟悉 NOS 的基本概念,如 Bucket、Object 、EndPoint 、AccessKeyId 和 AccessKeySecret 等。 本节您将看到如何快速的使用 NOS PHP SDK ,完成常用的操作,创建桶、上传文件、下载文件等。
常用类
常用类 | 备注 |
---|---|
NOSNosClient | NOS 客户端类,用户通过NosClient调用服务 |
NOSCoreNosException | NOS异常,在调用过程中去捕获这个异常,查看失败原因 |
基本操作
创建桶
您可以使用以下代码新建一个桶:
<?php use NOS\NosClient; use NOS\Core\NosException; $accessKeyId = "您的accessKeyId"; $accessKeySecret = "您的accessKeySecret"; $endPoint = "建桶时选择的的区域域名"; $bucket = "使用的桶名,注意命名规则"; try{ $nosClient = new NosClient($accessKeyId,$accessKeySecret,$endPoint); $nosClient->createBucket($bucket); } catch(NosException e){ print e->getMessage(); }
Attention:
桶名命名规则请参见 API 手册桶命名规范
更多的关于bucket的操作的信息,请参见 NOS-PHP-SDK Bucket管理
上传文件
对象(Object)是 NOS 中最基本的数据单元,您可以把它简单的理解为文件,以下代码可以实现简单的对象上传:
<?php use NOS\NosClient; use NOS\Core\NosException; $accessKeyId = "您的accessKeyId"; $accessKeySecret = "您的accessKeySecret"; $endPoint = "建桶时选择的的区域域名"; $bucket = "使用的桶名,注意命名规则"; $object = "使用的对象名,注意命名规则"; $content = "Hello NOS!"; try{ $nosClient = new NosClient($accessKeyId,$accessKeySecret,$endPoint); $nosClient->putObject($bucket,$object,$content); } catch(NosException e){ print e->getMessage(); }
Attention: 对象命名规则请参见 API 手册 对象
更多的上传文件信息,请参见 NOS-PHP-SDK 上传文件
下载文件
上传对象成功之后,您可以读取它的内容,以下代码可以实现文件的下载:
<?php use NOS\NosClient; use NOS\Core\NosException; $accessKeyId = "您的accessKeyId"; $accessKeySecret = "您的accessKeySecret"; $endPoint = "建桶时选择的的区域域名"; $bucket = "使用的桶名,注意命名规则"; $object = "使用的对象名,注意命名规则"; try{ $nosClient = new NosClient($accessKeyId,$accessKeySecret,$endPoint); $content = $nosClient->getObject($bucket,$object); print("object content: " . $content); } catch(NosException e){ print e->getMessage(); }
列举文件
当上传文件成功之后,可以查看桶中包含的文件列表,以下代码展示如何列举桶内的文件:
<?php use NOS\NosClient; use NOS\Core\NosException; $accessKeyId = "您的accessKeyId"; $accessKeySecret = "您的accessKeySecret"; $endPoint = "建桶时选择的的区域域名"; $bucket = "使用的桶名,注意命名规则"; try{ $nosClient = new NosClient($accessKeyId,$accessKeySecret,$endPoint); $listObjectInfo = $nosClient->listObjects($bucket); if (!empty($objectList)) { foreach ($objectList as $objectInfo) { print($objectInfo->getKey() . "\t" . $objectInfo->getSize() . "\t" . $objectInfo->getLastModified() . "\n"); } } } catch(NosException e){ print e->getMessage(); }
Note;
上面的代码默认列举100个object
更多的管理文件信息,请参见NOS-PHP-SDK 文件管理
删除文件
文件上传成功后,可以指定删除桶中的文件,以下代码实现桶中文件的删除:
<?php use NOS\NosClient; use NOS\Core\NosException; $accessKeyId = "您的accessKeyId"; $accessKeySecret = "您的accessKeySecret"; $endPoint = "建桶时选择的的区域域名"; $bucket = "使用的桶名,注意命名规则"; $object = "使用的对象名,注意命名规则"; try{ $nosClient = new NosClient($accessKeyId,$accessKeySecret,$endPoint); $content = $nosClient->deleteObject($bucket,$object); } catch(NosException e){ print e->getMessage(); }
返回结果处理
NosClient中的接口对应返回数据分为两类:
- Put,Delete 类接口返回 null,如果没有 NosException,即可认为操作成功
- Get,List 类接口返回对应的数据,如果没有 NosException,即可认为操作成功
例如:
<?php $bucketListInfo = $nosClient->listBuckets(); $bucketList = $bucketListInfo->getBucketList(); foreach($bucketList as $bucket) { print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreatedate() . "\n"); }
上面代码中的 $bucketListInfo 的数据类型是 NOS\Model\BucketListInfo
桶的管理
桶是 NOS 上的存储空间,也是计费、权限控制、日志记录等高级功能的管理实体。
新建桶
您可以使用 NosClient::createBucket 新建桶:
<?php /** * 创建一个桶 * acl 指的是bucket的访问控制权限,有两种,私有读写,公共读私有写。 * 私有读写就是只有bucket的拥有者或授权用户才有权限操作 * 公共读私有写,任意用户可以读,只有授权用户才能写 * 两种权限分别对应NosClient::NOS_ACL_TYPE_PRIVATE, * NosClient::NOS_ACL_TYPE_PUBLIC_READ, * * @param NosClient $nosClient NosClient实例 * @param string $bucket 要创建的bucket名字 * @return null */ function createBucket($nosClient, $bucket) { try { $nosClient->createBucket($bucket, NosClient::NOS_ACL_TYPE_PRIVATE); } catch (NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
Attention:
1. 桶的命名规范,请参见 基本概念 桶命名规范
2. 桶的名字全局唯一,不同用户之间的桶名也不能重复
3. 关于权限更加详细的说明,请参见: 桶的属性
判断桶是否存在
您可以使用 NosClient::doesBucketExist 判断桶是否存在:
<?php /** * 判断Bucket是否存在 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 桶名称 */ function doesBucketExist($nosClient, $bucket) { try { $res = $nosClient->doesBucketExist($bucket); } catch (NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } if ($res === true) { print(__FUNCTION__ . ": OK" . "\n"); } else { print(__FUNCTION__ . ": FAILED" . "\n"); } }
列出用户所有的桶
您可以使用 NosClient::listBuckets 列出当前用户所有的桶:
<?php /** * 列出用户所有的Bucket * * @param NosClient $nosClient NosClient实例 * @return null */ function listBuckets($nosClient) { $bucketList = null; try{ $bucketListInfo = $nosClient->listBuckets(); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } $bucketList = $bucketListInfo->getBucketList(); foreach($bucketList as $bucket) { print($bucket->getName() . "\t" . $bucket->getCreatedate() . "\n"); } }
删除桶
您可以使用NosClient::deleteBucket 删除空桶:
<?php /** * 删除存储空间 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 待删除的桶名称 * @return null */ function deleteBucket($nosClient, $bucket) { try{ $nosClient->deleteBucket($bucket); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
Attention:
1. 如果存储空间不为空(存储空间中有文件或者分片上传的分片),则存储空间无法删除;
2. 必须先删除存储空间中的所有文件和分片后,存储空间才能成功删除。
设置桶的ACL属性
除了在创建桶的时候可以指定桶的ACL属性之外,也可以根据自己的业务需求对桶的ACL进行修改,这个操作只有桶的拥有者有权限修改,关于桶的权限修改请参考: 桶的属性修改
桶存在两种权限:
权限 | 备注 |
---|---|
私有读写 | NosClient::NOS_ACL_TYPE_PRIVATE |
公共读私有写 | NosClient::NOS_ACL_TYPE_PUBLIC_READ |
您可以使用 NosClient::putBucketAcl 设置桶的访问权限:
<?php /** * 设置bucket的acl配置 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 桶名称 * @return null */ function putBucketAcl($nosClient, $bucket) { $acl = NosClient::NOS_ACL_TYPE_PRIVATE; try { $nosClient->putBucketAcl($bucket, $acl); } catch (NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
获取桶的ACL属性
您可以使用 NosClient::getBucketAcl 获取桶的访问权限:
<?php /** * 获取bucket的acl配置 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 桶名称 * @return null */ function getBucketAcl($nosClient, $bucket) { try { $res = $nosClient->getBucketAcl($bucket); } catch (NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); print('acl: ' . $res); }
获取桶所处的分区
您可以使用 NosClient::getBucketLocation 获取桶所处的分区:
<?php /** * 获取bucket的location配置 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 桶名称 * @return null */ function getBucketAcl($nosClient, $bucket) { try { $res = $nosClient->getLocation($bucket); } catch (NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); print('location: ' . $res); }
文件上传
在 NOS 中用户的基本操作单元是对象,亦可以理解为文件,NOS PHP SDK提供了丰富的上传接口,可以通过以下的方式上传文件:
- 字符串上传
- 本地文件上传
- 分片上传
字符串上传、本地文件上传最大为100M,分片上传没有限制
字符串上传
您可以使用 NosClient::putObject 上传字符串内容到文件中,具体实现如下:
<?php /** * 上传字符串作为object的内容 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @return null */ function putObject($nosClient, $bucket) { $object = "nos-php-sdk-test/upload-test-object-name.txt"; $content = file_get_contents(__FILE__); try{ $nosClient->putObject($bucket, $object, $content); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
本地文件上传
您可以使用 NosClient::uploadFile 上传文件内容,具体实现如下:
<?php /** * 上传指定的本地文件内容 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @return null */ function uploadFile($nosClient, $bucket) { $object = "nos-php-sdk-test/upload-test-object-name.txt"; $filePath = __FILE__; try{ $nosClient->uploadFile($bucket, $object, $filePath); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
Attention:
1. 上传的文件内容不超过100M
分片上传
除了通过putObject接口上传文件到NOS之外,NOS还提供了另外一种上传模式-分片上传,用户可以在如下应用场景内(但不限于此),使用分片上传模式,如:
- 需支持断点上传
- 上传超过100M的文件
- 网络条件较差,经常和NOS服务器断开连接
- 上传文件之前无法确定文件的大小
分片上传本地文件
您可以使用 NosClient::multiuploadFile 来上传一个文件,该方法封装了细节,会根据传入的文件及分片的大小自动选择上传方式,对于分片大小小于文件大下的情况下会使用分片上传:
<?php /** * 通过multipart上传文件 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @return null */ function multiuploadFile($nosClient, $bucket) { $object = "test/multipart-test.txt"; $file = __FILE__; try{ $nosClient->multiuploadFile($bucket, $object, $file); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
Attention:
1. 默认的分片大小为5M
原始接口分片上传
您可以使用原始的分片上传接口进行分片上传,一般流程如下所示:
- 初始化一个分片上传任务(InitiateMultipartUpload)
- 逐个或并行上传分片(UploadPart)
- 完成分片上传(CompleteMultipartUpload)或者取消分片上传(AbortMultipartUpload)
下面通过一个完整的示例说明了如何通过原始的api接口一步一步的进行分片上传操作,如果用户需要做断点续传等高级操作,可以参考下面代码:
<?php /** * 使用基本的api分阶段进行分片上传 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @throws NosException */ function putObjectByRawApis($nosClient, $bucket) { $object = "test/multipart-test.txt"; /** * step 1. 初始化一个分块上传事件, 也就是初始化上传Multipart, 获取upload id */ try{ $uploadId = $nosClient->initiateMultipartUpload($bucket, $object); } catch(NosException $e) { printf(__FUNCTION__ . ": initiateMultipartUpload FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": initiateMultipartUpload OK" . "\n"); /* * step 2. 上传分片 */ // 分片大小10M $partSize = 10 * 1024 * 1024; $uploadFile = __FILE__; $uploadFileSize = filesize($uploadFile); $pieces = $nosClient->generateMultiuploadParts($uploadFileSize, $partSize); $responseUploadPart = array(); $uploadPosition = 0; $isCheckMd5 = true; foreach ($pieces as $i => $piece) { $fromPos = $uploadPosition + (integer)$piece[NosClient::NOS_SEEK_TO]; $toPos = (integer)$piece[NosClient::NOS_LENGTH] + $fromPos - 1; $upOptions = array( $nosClient::NOS_FILE_UPLOAD => $uploadFile, $nosClient::NOS_PART_NUM => ($i + 1), $nosClient::NOS_SEEK_TO => $fromPos, $nosClient::NOS_LENGTH => $toPos - $fromPos + 1, $nosClient::NOS_CHECK_MD5 => $isCheckMd5, ); if ($isCheckMd5) { $contentMd5 = NosUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos); $upOptions[$nosClient::NOS_CONTENT_MD5] = $contentMd5; } //2. 将每一分片上传到 NOS try { $responseUploadPart[] = $nosClient->uploadPart($bucket, $object, $uploadId, $upOptions); } catch(NosException $e) { printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} FAILED\n"); printf($e->getMessage() . "\n"); return; } printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} OK\n"); } $uploadParts = array(); foreach ($responseUploadPart as $i => $eTag) { $uploadParts[] = array( 'PartNumber' => ($i + 1), 'ETag' => $eTag, ); } /** * step 3. 完成上传 */ try { $nosClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts); } catch(NosException $e) { printf(__FUNCTION__ . ": completeMultipartUpload FAILED\n"); printf($e->getMessage() . "\n"); return; } printf(__FUNCTION__ . ": completeMultipartUpload OK\n"); }
Attention:
1. 上面程序一共分为三个步骤:1. initiate 2. uploadPart 3. complete2. UploadPart 方法要求除最后一个Part以外,其他的Part大小都要大于或等于5M。但是Upload Part接口并不会立即校验上传Part的大小(因为不知道是否为最后一块);只有当Complete Multipart Upload的时候才会校验。
3. Part号码的范围是1~10000。如果超出这个范围,NOS 将返回InvalidArgument的错误码。
4. 每次上传Part时都要把流定位到此次上传块开头所对应的位置。
5. 分片上传任务初始化或上传部分分片后,可以使用abortMultipartUpload接口中止分片上传事件。当分片上传事件被中止后,就不能再使用这个Upload ID做任何操作,已经上传的分片数据也会被删除。
6. 每次上传Part之后,NOS 的返回结果会包含一个 PartETag 对象,它是上传块的ETag与块编号(PartNumber)的组合。在后续完成分片上传的步骤中会用到它,因此我们需要将其保存起来,然后在第三步complete的时候使用,具体操作参考上面代码。
查看已经上传的分片
查看已经上传的分片可以罗列出指定 Upload ID ( InitiateMultipartUpload 时获取)所属的所有已经上传成功的分片,您可以通过 NosClient::listParts 接口获取已经上传的分片,可以参考以下代码:
/** * 查看已上传的分片 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @param string $uploadId upload Id * @return null */ function listParts($nosClient, $bucket, $uploadId) { $object = "nos-php-sdk-test/upload-test-object-name.txt"; try{ $options = array(); $options['max-parts'] = 100; $optiosn['part-number-marker'] = '10'; $listPartsInfo = $nosClient->listParts($bucket, $object, $upload_id,$options); foreach ($listPartsInfo->getListPart() as $partInfo) { print($partInfo->getPartNumber() . "\t" . $partInfo->getSize() . "\t" . $partInfo->getETag() . "\t" . $partInfo->getLastModified() . "\n"); } } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
查看已经上传的分片可以指定以下参数:
参数 | 描述 |
---|---|
max-parts | 响应中的limit个数 类型:整型 |
part-number-marker | 分块号的界限,只有更大的分块号会被列出来。 类型:字符串 |
查看当前正在进行的分片上传任务
查看正在进行的分片上传任务可以罗列出正在进行,还未完成的分片上传任务,您可以通过 NosClient::listMultipartUploads 接口当前的上传任务,可以参考以下代码:
<?php /** * 获取当前未完成的分片上传列表 * * @param $nosClient NosClient * @param $bucket string */ function listMultipartUploads($nosClient, $bucket) { $options = array( 'max-uploads' => 100, 'key-marker' => '' ); try { $listMultipartUploadInfo = $nosClient->listMultipartUploads($bucket, $options); } catch(NosException $e) { printf(__FUNCTION__ . ": listMultipartUploads FAILED\n"); printf($e->getMessage() . "\n"); return; } printf(__FUNCTION__ . ": listMultipartUploads OK\n"); $listUploadInfo = $listMultipartUploadInfo->getUploads(); var_dump($listUploadInfo); }
上述代码中使用的options参数如下:
参数值 | 描述 |
---|---|
key-marker | 指定某一uploads key,只有大于该key-marker的才会被列出 |
max-uploads | 最多返回max-uploads条记录,默认1000 |
设置文件元信息
文件元数据( object meta ),是上传到 NOS 的文件属性描述信息:分为 http 标准属性和用户自定义元数据。文件元信息可以在各种上传方式(字符串上传、文件上传、分片上传)或 copy 文件时进行设置,元数据大小写不敏感。
设定http header NOS 允许用户自定义http Header。http header相关信息请参考 RFC2616,几个常用的header说明如下:
名称 | 描述 |
---|---|
Content-MD5 | 文件数据校验,设置了该值后 NOS 会启用文件内容MD5校验,把您提供的MD5与文件的MD5比较,不一致会抛出错误 |
Content-Type | 文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,如果没有扩展名则填默认值 |
Content-Disposition | 指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称 |
Content-Length | 上传的文件的长度,超过流/文件的长度会截断,不足为实际值 |
Expires | 缓存过期时间,NOS 未使用,格式是格林威治时间(GMT) |
Cache-Control | 指定该Object被下载时的网页的缓存行为 |
下面的源代码实现了上传文件时设置Http header:
/** * 上传时设置文件的元数据 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @return null */ function putObject($nosClient, $bucket) { $object = "nos-php-sdk-test/upload-test-object-name.txt"; $content = file_get_contents(__FILE__); $options = array( NosClient::NOS_HEADERS => array( 'Expires' => '2016-12-12 08:00:00', 'Content-Disposition' => 'attachment; filename="xxxxxx"', )); try{ $nosClient->putObject($bucket, $object, $content, $options); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
用户自定义元数据
NOS 支持用户自定义对象元数据,上传时可以指定对象自定义元数据,数据放在http头中传输,以 x-nos-meta-开头,以下源代码实现对象自定义元数据上传:
<?php /** * 上传时设置文件的自定义元数据 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @return null */ function putObject($nosClient, $bucket) { $object = "nos-php-sdk-test/upload-test-object-name.txt"; $content = file_get_contents(__FILE__); $options = array(NosClient::NOS_HEADERS => array( 'x-nos-meta-self-define-title' => 'user define meta info', )); try{ $nosClient->putObject($bucket, $object, $content, $options); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
上传时校验MD5
为了确保 PHP SDK 发送的数 NOS 服务端接收到的数据一致,NOS 支持MD5校验。文件上传时(字符串上传、文件上传、分片上传)默认关闭 MD5,如果您需要打开 MD5 校验,请上传文件的 options 设置。
下面的代码实现了上传时开启 MD5 校验:
<?php /** * 上传时开启MD5校验 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @return null */ function putObject($nosClient, $bucket) { $object = "nos-php-sdk-test/upload-test-object-name.txt"; $options = array(NosClient::NOS_CHECK_MD5 => true); try{ $nosClient->uploadFile($bucket, $object, __FILE__, $options); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
Attention:
1. 校验MD5会有一定的性能损失;
文件下载
NOS PHP SDK 提供了丰富的文件下载接口,用户可以通过以下方式从 NOS 获取文件:
- 下载文件到内存
- 下载到本地文件
- 分段下载
- 条件下载
下载文件到内存
以下源代码实现下载文件到内存中:
<?php /** * 获取object的内容 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 桶名称 * @return null */ function getObject($nosClient, $bucket) { $object = "nos-php-sdk-test/upload-test-object-name.txt"; try{ $content = $nosClient->getObject($bucket, $object); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
下载文件到本地文件
<?php /** * get_object_to_local_file * * 获取object * 将object下载到指定的文件 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @return null */ function getObjectToLocalFile($nosClient, $bucket) { $object = "nos-php-sdk-test/download-test-object-name.txt"; $localfile = "download-test-object-name.txt"; $options = array( NosClient::NOS_FILE_DOWNLOAD => $localfile, ); try{ $nosClient->getObject($bucket, $object, $options); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK, please check localfile: 'upload-test-object-name.txt'" . "\n"); }
范围下载
如果存储在NOS中的文件较大,并且您只需要其中的一部分内容,您可以使用范围下载,下载指定范围的数据,如果指定的下载范围为”0-100”,则返回结果为第0字节到第100字节的数据,返回的数据包含第100字节,即[0,100],如果指定的范围无效则下载整个文件,以下源代码获取[0,100]字节的内容:
<?php /** * 获取object的内容 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @return null */ function getObject($nosClient, $bucket) { $object = "nos-php-sdk-test/upload-test-object-name.txt"; try{ $options = array(NosClient::NOS_RANGE => '0-100'); $content = $nosClient->getObject($bucket, $object, $options); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
Attention:
1. 下载内容也可以存储到文件中 2. 注意下载的区间为闭区间
条件下载
下载文件时,可以指定限定条件,满足限定条件时下载,不满足时报错,不下载文件。可以使用的限定条件如下:
参数 | 说明 | NosClient对应值 |
---|---|---|
If-Modified-Since | 如果指定的时间早于实际修改时间,则正常传送。否则返回错误 | NosClient::NOS_IF_MODIFIED_SINCE |
<?php /** * 如果文件在指定的时间之后修改过,则下载文件 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @return null */ function getObject($nosClient, $bucket) { $object = "nos-php-sdk-test/upload-test-object-name.txt"; try{ $options = array( NosClient::NOS_HEADERS => array( NosClient::NOS_IF_MODIFIED_SINCE => "Fri, 13 Nov 2016 14:47:53 GMT"), ); $content = $nosClient->getObject($bucket, $object, $options); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
Attention:
1. 下载内容也可以存储到文件中
文件管理
在NOS中,用户可以通过一系列的接口管理桶(Bucket)中的文件(Object),比如ListObjects,DeleteObject,CopyObject,DoesObjectExist等。
列出桶中的文件
您可以使用NosClient::listObjects列出存储中间中的文件:
<?php /** * 列出Bucket内所有目录和文件, 根据返回的nextMarker循环调用listObjects接口得到所有文件 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @return null */ function listAllObjects($nosClient, $bucket) { for ($i = 0; $i < 100; $i += 1) { $nosClient->putObject($bucket, "dir/obj" . strval($i), "hi"); } $prefix = 'dir/'; $delimiter = '/'; $nextMarker = ''; $maxkeys = 30; while (true) { $options = array( 'delimiter' => $delimiter, 'prefix' => $prefix, 'max-keys' => $maxkeys, 'marker' => $nextMarker, ); var_dump($options); try { $listObjectInfo = $nosClient->listObjects($bucket, $options); } catch (NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } var_dump($listObjectInfo); // 得到nextMarker,从上一次listObjects读到的最后一个文件的下一个文件开始继续获取文件列表 $nextMarker = $listObjectInfo->getNextMarker(); $listObject = $listObjectInfo->getObjectList(); var_dump($listObject); if ($nextMarker === '') { break; } } }
上述代码中的$options中的参数如下所示:
参数 | 说明 |
---|---|
delimiter | 用于对Object名字进行分组的字符。所有名字包含指定的前缀且第一次出现delimiter字符之间的object作为一组元素 |
prefix | 限定返回的object key必须以prefix作为前缀。注意使用prefix查询时,返回的key中仍会包含prefix |
max-keys | 限定此次返回object的最大数,如果不设定,默认为100 |
marker | 设定结果从marker之后按字母排序的第一个开始返回 |
Note:
上述表中的参数都是可选参数
判断文件是否存在
您可以使用NosClient::doesObjectExist判断文件是否存在:
<?php /** * 判断object是否存在 * * @param NosClient $nosClient NosClient实例 * @param string $bucket bucket名字 * @return null */ function doesObjectExist($nosClient, $bucket) { $object = "nos-php-sdk-test/upload-test-object-name.txt"; try{ $exist = $nosClient->doesObjectExist($bucket, $object); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); var_dump($exist); }
删除单个文件
您可以使用NosClient::deleteObject删除单个需要删除的文件:
<?php /** * 删除object * * @param NosClient $nosClient NosClient实例 * @param string $bucket bucket名字 * @return null */ function deleteObject($nosClient, $bucket) { $object = "nos-php-sdk-test/upload-test-object-name.txt"; try{ $nosClient->deleteObject($bucket, $object); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
删除多个文件
您可以使用NosClient::deleteObjects批量删除文件:
<?php /** * 批量删除object * * @param NosClient $nosClient NosClient实例 * @param string $bucket bucket名字 * @return null */ function deleteObjects($nosClient, $bucket) { $objects = array(); $objects[] = "nos-php-sdk-test/upload-test-object-name.txt"; $objects[] = "nos-php-sdk-test/upload-test-object-name.txt.copy"; try{ $nosClient->deleteObjects($bucket, $objects); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
拷贝文件
您可以使用NosClient::copyObject拷贝文件:
<?php /** * 拷贝object * * @param NosClient $nosClient NosClient实例 * @param string $bucket bucket名字 * @return null */ function copyObject($nosClient, $bucket) { $from_bucket = $bucket; $from_object = "nos-php-sdk-test/upload-test-object-name.txt"; $to_bucket = $bucket; $to_object = $from_object . '.copy'; try{ $nosClient->copyObject($from_bucket, $from_object, $to_bucket, $to_object); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
Attention:
1. 支持跨桶的文件copy
移动文件
您可以使用NosClient::moveObject移动文件:
<?php /** * 移动Object * * @param NosClient $nosClient NosClient实例 * @param string $bucket bucket名字 * @return null */ function copyObject($nosClient, $bucket) { $from_bucket = $bucket; $from_object = "nos-php-sdk-test/upload-test-object-name.txt"; $to_bucket = $bucket; $to_object = $from_object . '.move'; try{ $nosClient->moveObject($from_bucket, $from_object, $to_bucket, $to_object); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); }
Attention:
1. 暂时不支持跨桶的文件move
修改文件元信息
暂时不提供此类方法
获取文件的文件元信息
您可以使用NosClient::getObjectMeta获取对象的元数据信息:
<?php /** * 获取object meta, 也就是getObjectMeta接口 * * @param NosClient $nosClient NosClient实例 * @param string $bucket 存储空间名称 * @return null */ function getObjectMeta($nosClient, $bucket) { $object = "nos-php-sdk-test/upload-test-object-name.txt"; try { $objectMeta = $nosClient->getObjectMeta($bucket, $object); } catch (NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": OK" . "\n"); if (isset($objectMeta[strtolower('Content-Disposition')]) && 'attachment; filename="xxxxxx"' === $objectMeta[strtolower('Content-Disposition')] ) { print(__FUNCTION__ . ": ObjectMeta checked OK" . "\n"); } else { print(__FUNCTION__ . ": ObjectMeta checked FAILED" . "\n"); } }
Attention:
1. 获取的元数据通过一个array返回,返回值为HTTP头类型的元数据与用户自定义元数据 2. 元数据名的大小均为小写
授权访问
通过生成签名URL的形式提供给用户一个临时的访问URL。在生成URL时,您可以指定URL过期的时间,从而限制用户长时间访问。
生成私有下载链接 生成 GetObject 的签名 url 示例如下:
<?php /** * 生成GetObject的签名url,主要用于私有权限下的读访问控制 * * @param $nosClient NosClient NosClient实例 * @param $bucket string bucket名称 * @return null */ function getSignedUrlForGettingObject($nosClient, $bucket) { $object = "test/test-signature-test-upload-and-download.txt"; $timeout = 3600; // URL的有效期是3600秒 try{ $signedUrl = $nosClient->signUrl($bucket, $object, $timeout); } catch(NosException $e) { printf(__FUNCTION__ . ": FAILED\n"); printf($e->getMessage() . "\n"); return; } print(__FUNCTION__ . ": signedUrl: " . $signedUrl. "\n"); /** * 可以类似的代码来访问签名的URL,也可以输入到浏览器中去访问 */ $request = new RequestCore($signedUrl); $request->set_method('GET'); $request->send_request(); $res = new ResponseCore($request->get_response_header(), $request->get_response_body(), $request->get_response_code()); if ($res->isOK()) { print(__FUNCTION__ . ": OK" . "\n"); } else { print(__FUNCTION__ . ": FAILED" . "\n"); }; }
最后更新:2017-01-03 10:48:53