对象存储 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