You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

623 lines
24 KiB

<?php
/**
* 阿里云对象存储 OSS
* @package model
*/
include_once (SERVER_ROOT . "/model/mBase.php");
include_once SERVER_ROOT . "/library/aliyun/OSS/OssClient.php";
class mAliyunOSS extends mBase{
// oss节点
public $endpoint = ALIYUN_OSS_END_POINT;
/**
* 判断存储空间bucket是否存在
* @param unknown $bucket 存储空间
* @return boolean
*/
public function isExistBucket($bucket) {
try {
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
$res = $ossClient->doesBucketExist($bucket);
} catch (OssException $e) {
$this->setError($e->getMessage());
return false;
}
if ($res === false) return false;
return true;
}
/**
* 列举存储空间
* @return boolean|string
*/
public function getBucketList() {
try{
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
$bucketListInfo = $ossClient->listBuckets();
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
$bucketList = $bucketListInfo->getBucketList();
$nlist = array();
foreach($bucketList as $key => $bucket) {
$nlist[$key]['location'] = $bucket->getLocation();
$nlist[$key]['name'] = $bucket->getName();
$nlist[$key]['create_date'] = $bucket->getCreatedate();
}
return $nlist;
}
/**
* 简单上传 上传字符串
* @param unknown $bucket 存储空间名称
* @param unknown $oss_save_path oss下文件路径及名称
* @param unknown $content 字符串内容
*/
public function simpleUploadStr($bucket, $oss_save_path, $content) {
try{
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
$ossClient->putObject($bucket, $oss_save_path, $content);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
return true;
}
/**
* 简单上传 上传文件
* @param unknown $bucket 存储空间名称
* @param unknown $oss_save_path oss下文件路径及名称
* @param unknown $upload_file_path 需要上传到oss文件的路径
*/
public function simpleUploadFile($bucket, $oss_save_path, $upload_file_path) {
try{
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
$ossClient->uploadFile($bucket, $oss_save_path, $upload_file_path);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
return true;
}
/**
* 分片上传
* @param unknown $bucket 存储空间名称
* @param unknown $oss_save_path oss下文件路径及名称
* @param unknown $upload_file_path 需要上传到oss文件的路径
* @return boolean
*/
public function multiPartUpload($bucket, $oss_save_path, $upload_file_path) {
/**
* 步骤1:初始化一个分片上传事件,获取uploadId。
*/
try{
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
//返回uploadId,它是分片上传事件的唯一标识,您可以根据这个ID来发起相关的操作,如取消分片上传、查询分片上传等。
$uploadId = $ossClient->initiateMultipartUpload($bucket, $oss_save_path);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
/*
* 步骤2:上传分片。
*/
$partSize = ALIYUN_OSS_PARTS_UPLOAD_SIZE * 1024 * 1024;
$uploadFileSize = filesize($upload_file_path);
$pieces = $ossClient->generateMultiuploadParts($uploadFileSize, $partSize);
$responseUploadPart = array();
$uploadPosition = 0;
$isCheckMd5 = true;
foreach ($pieces as $i => $piece) {
$fromPos = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO];
$toPos = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1;
$upOptions = array(
$ossClient::OSS_FILE_UPLOAD => $upload_file_path,
$ossClient::OSS_PART_NUM => ($i + 1),
$ossClient::OSS_SEEK_TO => $fromPos,
$ossClient::OSS_LENGTH => $toPos - $fromPos + 1,
$ossClient::OSS_CHECK_MD5 => $isCheckMd5,
);
// MD5校验。
if ($isCheckMd5) {
$contentMd5 = OssUtil::getMd5SumForFile($upload_file_path, $fromPos, $toPos);
$upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5;
}
try {
// 上传分片。
$responseUploadPart[] = $ossClient->uploadPart($bucket, $oss_save_path, $uploadId, $upOptions);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
}
// $uploadParts是由每个分片的ETag和分片号(PartNumber)组成的数组。
$uploadParts = array();
foreach ($responseUploadPart as $i => $eTag) {
$uploadParts[] = array(
'PartNumber' => ($i + 1),
'ETag' => $eTag,
);
}
/**
* 步骤3:完成上传。
*/
try {
// 在执行该操作时,需要提供所有有效的$uploadParts。OSS收到提交的$uploadParts后,会逐一验证每个分片的有效性。当所有的数据分片验证通过后,OSS将把这些分片组合成一个完整的文件。
$ossClient->completeMultipartUpload($bucket, $oss_save_path, $uploadId, $uploadParts);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
return true;
}
/**
* 上传一个目录下所有文件
* @param unknown $bucket 存储空间名称
* @param unknown $dir 本地目录,目录下只能是文件 如/a/b/1.txt, /a/b/2.txt, /a/b/c/3.txt dir='/a/b' c目录不会上传
* @param unknown $oss_save_path 需要保存到oss路径
*/
public function multiPartUploadDir($bucket, $dir, $oss_save_path) {
try {
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
$ossClient->uploadDir($bucket, $oss_save_path, $dir);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
return true;
}
/**
* 下载文件到本地
* @param unknown $bucket 存储空间名称
* @param unknown $oss_save_path oss下文件路径及名称
* @param unknown $local_path 保存到本地路径
*/
public function downloadToLocal($bucket, $oss_save_path, $local_path) {
$dir = dirname($local_path);
if(!is_dir($dir)) {
mkdir($dir, 0775, true);
chown($dir, 'nobody');
chgrp($dir, 'nobody');
}
$options = array(
OssClient::OSS_FILE_DOWNLOAD => $local_path
);
try{
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
$ossClient->getObject($bucket, $oss_save_path, $options);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
return true;
}
/**
* 下载文件到本地内存
* @param unknown $bucket 存储空间名称
* @param unknown $oss_save_path oss下文件路径及名称 如abc/efg/123.jpg
* @return void|string
*/
public function downloadToLocalMemory($bucket, $oss_save_path) {
try{
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
$content = $ossClient->getObject($bucket, $oss_save_path);
} catch(OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
return $content;
}
/**
* 删除单个文件
* @param unknown $bucket 存储空间名称
* @param unknown $oss_save_path oss下文件路径及名称 如abc/efg/123.jpg
* @return boolean
*/
public function delSingleFile($bucket, $oss_save_path) {
try{
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
$ossClient->deleteObject($bucket, $oss_save_path);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
return true;
}
/**
* 删除多个文件
* @param unknown $bucket 存储空间名称
* @param unknown $oss_save_path_files oss下文件路径及名称数组 如array('abc/efg/123.jpg', 'abc/efg/234.jpg')
* @return boolean
*/
public function delMultiFile($bucket, $oss_save_path_files) {
try{
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
$ossClient->deleteObjects($bucket, $oss_save_path_files);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
return true;
}
/**
* 列举文件列表
* @param unknown $bucket 存储空间名称
* @param unknown $oss_dir oss存储目录 为空列举所有文件
* @param unknown $marker 下一次查询标记(文件名)
* @param number $limit 每次查询数量
*/
public function getOssFileList($bucket, $oss_dir=null, $marker=null, $limit=10) {
$prefix = $oss_dir;
$delimiter = '';
$nextMarker = $marker;
$maxkeys = $limit;
$options = array(
'prefix' => $prefix,
'delimiter' => $delimiter,
'max-keys' => $maxkeys,
'marker' => $nextMarker,
);
// prefix
// 对Object名字进行分组的字符。
// 所有Object名字包含指定的前缀,第一次出现Delimiter字符之间的Object作为一组元素(即CommonPrefixes)。
// delimiter
// 限定返回文件的Key必须以Prefix作为前缀。
// 如果把Prefix设为某个文件夹名,就可以列举以此Prefix开头的文件,即该文件夹下递归的所有文件和子文件夹。
// 在设置Prefix的基础上增加设置Delimiter为 / 时,返回值就只列举该文件夹下的文件,文件夹下的子文件夹名返回在CommonPrefixes中,子文件夹下递归的所有文件和文件夹不显示。
// 例如,一个Bucket中存在三个Object : fun/test.jpg, fun/movie/001.avi,fun/movie/007.avi。若设定Prefix为 fun/,则返回三个Object;如果增加设定Delimiter为 /,则返回fun/test.jpg和fun/movie/ 。
// 参数的长度必须小于1024字节。使用Prefix查询时,返回的Key中仍会包含Prefix。
// marker
// 设定从Marker之后按字母排序开始返回Object。
// Marker用来实现分页显示效果,参数的长度必须小于1024字节。在做条件查询时,即使Marker在列表中不存在,也会从符合Marker字母排序的下一个开始打印。
// max-keys
// 指定返回Object的最大数。
// 取值:大于0小于1000,默认值:100。
// 如果因为Max-keys的设定无法一次完成列举,返回结果会附加一个<NextMarker>作为下一次列举的Marker。
try {
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
$listObjectInfo = $ossClient->listObjects($bucket, $options);
} catch (OssException $e) {
$this->setError($e->getMessage());
return false;
}
$nlist['bucketName'] = $listObjectInfo->getBucketName();
$nlist['prefix'] = $listObjectInfo->getPrefix();
$nlist['marker'] = $listObjectInfo->getMarker();
$nlist['nextMarker'] = $listObjectInfo->getNextMarker();
$nlist['maxKeys'] = $listObjectInfo->getMaxKeys();
$nlist['delimiter'] = $listObjectInfo->getDelimiter();
$nlist['isTruncated'] = $listObjectInfo->getIsTruncated();
$nlist['objectList'] = array();
$nlist['prefixList'] = array();
$objectList = $listObjectInfo->getObjectList(); // object list
$prefixList = $listObjectInfo->getPrefixList(); // directory list
if (!empty($objectList)) {
foreach ($objectList as $objectInfo) {
$nlist['objectList'][] = $objectInfo->getKey();
}
}
if (!empty($prefixList)) {
foreach ($prefixList as $prefixInfo) {
$nlist['prefixList'][] = $prefixInfo->getPrefix();
}
}
return $nlist;
}
/**
* 上传文件到oss
* @param unknown $bucket 存储空间名称
* @param unknown $oss_save_path oss下文件路径及名称
* @param unknown $upload_file_path 需要上传到oss文件的路径
* @return boolean
*/
public function uploadFileToOss($bucket, $oss_save_path, $upload_file_path) {
$file_size = filesize($upload_file_path);
if($file_size>ALIYUN_OSS_PARTS_UPLOAD_SIZE) {
$res = $this->multiPartUpload($bucket, $oss_save_path, $upload_file_path);
} else {
$res = $this->simpleUploadFile($bucket, $oss_save_path, $upload_file_path);
}
if(!$res) {
$this->setError($this->getError());
return false;
}
return true;
}
public function downFileFromOss($oss_type, $bucket, $oss_dir=null, $marker=null, $limit=1) {
$list = $this->getOssFileList($bucket, $oss_dir, $marker, $limit);
foreach ($list['objectList'] as $file) {
$local_path = $this->getLocalSavePath($oss_type, $file);
$res = $this->downloadToLocal($bucket, $file, $local_path);
// 首页私有模板 需要解压
if($oss_type == OSS_FILE_PRI_TPL) {
$dir = dirname($local_path);
$pobj = new mPaper();
$pobj->unZipRar($local_path, $dir);
}
}
if($list['isTruncated']=='false') return true;
$this->downFileFromOss($oss_type, $bucket, $oss_dir, $list['nextMarker'], $limit);
return true;
}
/**
* 获取本地保存目录
* @param unknown $oss_type
* @param unknown $oss_save_path
*/
public function getLocalSavePath($oss_type, $oss_save_path) {
switch ($oss_type) {
case OSS_FILE_REPORT:
case OSS_FILE_PAPER:
case OSS_FILE_PAPER_MIJI:
case OSS_FILE_PRI_TPL:
case OSS_FILE_WXPAY_CERT:
case OSS_FILE_WXCOUPON_PIC:
case OSS_FILE_MP_ACTIVITY_IMG:
$savepath = DATACENTER_ROOT.'/'.$oss_save_path;
break;
case OSS_FILE_REPORT_PARAGRAPH:
break;
case OSS_FILE_SITE_LOGO:
setlocale(LC_ALL, 'zh_CN.UTF-8');
$pathinfo = pathinfo($oss_save_path);
$basename = $pathinfo['basename'];
$savepath = DATACENTER_ROOT.'/assets/checksite/'.$basename;
break;
case OSS_FILE_SERVICE_ICO:
setlocale(LC_ALL, 'zh_CN.UTF-8');
$pathinfo = pathinfo($oss_save_path);
$basename = $pathinfo['basename'];
$savepath = DATACENTER_ROOT.'/assets/ico/'.$basename;
break;
default:
$savepath = DATACENTER_ROOT.'/'.$oss_save_path;
break;
}
$dirname = dirname($savepath);
if(!is_dir($dirname)) {
mkdir($dirname, 0755, true); // true代表层级创建
chown($dirname, 'nobody');
chgrp($dirname, 'nobody');
}
return $savepath;
}
/**
* 获取oss保存目录
* @param unknown $oss_type
* @param unknown $localpath
* @return string
*/
public function getOssSavePath($oss_type, $localpath) {
switch ($oss_type) {
case OSS_FILE_REPORT:
case OSS_FILE_PAPER:
case OSS_FILE_PAPER_MIJI:
case OSS_FILE_PRI_TPL:
case OSS_FILE_WXPAY_CERT:
case OSS_FILE_WXCOUPON_PIC:
case OSS_FILE_MP_ACTIVITY_IMG:
$savepath = trim(str_replace('datacenter', '', $localpath), '/');
break;
case OSS_FILE_REPORT_PARAGRAPH:
break;
case OSS_FILE_SITE_LOGO:
case OSS_FILE_SERVICE_ICO:
setlocale(LC_ALL, 'zh_CN.UTF-8');
$pathinfo = pathinfo($localpath);
$basename = $pathinfo['basename'];
$savepath = $GLOBALS['ossfile2savedir'][$oss_type]."/".$basename;
break;
default:
$savepath = trim(str_replace('datacenter', '', $localpath), '/');
break;
}
return $savepath;
}
public function isExist($bucket, $object) {
try{
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
$exist = $ossClient->doesObjectExist($bucket, $object);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
return $exist;
}
public function getFileUrl($bucket, $object, $timeout=60) {
try{
$ossClient = new OssClient(ALIYUN_OSS_ACCESS_KEY_ID, ALIYUN_OSS_ACCESS_KEY_SECRET, $this->endpoint);
$exist = $ossClient->signUrl($bucket, $object, $timeout);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
return $exist;
}
# 下方为临时方法 用完即删
/**
* 列举文件列表
* @param unknown $bucket 存储空间名称
* @param unknown $oss_dir oss存储目录 为空列举所有文件
* @param unknown $marker 下一次查询标记(文件名)
* @param number $limit 每次查询数量
*/
public function getOssFileList2($bucket, $oss_dir=null, $marker=null, $limit=1) {
$prefix = $oss_dir;
$delimiter = '';
$nextMarker = $marker;
$maxkeys = $limit;
$options = array(
'prefix' => $prefix,
'delimiter' => $delimiter,
'max-keys' => $maxkeys,
'marker' => $nextMarker,
);
// prefix
// 对Object名字进行分组的字符。
// 所有Object名字包含指定的前缀,第一次出现Delimiter字符之间的Object作为一组元素(即CommonPrefixes)。
// delimiter
// 限定返回文件的Key必须以Prefix作为前缀。
// 如果把Prefix设为某个文件夹名,就可以列举以此Prefix开头的文件,即该文件夹下递归的所有文件和子文件夹。
// 在设置Prefix的基础上增加设置Delimiter为 / 时,返回值就只列举该文件夹下的文件,文件夹下的子文件夹名返回在CommonPrefixes中,子文件夹下递归的所有文件和文件夹不显示。
// 例如,一个Bucket中存在三个Object : fun/test.jpg, fun/movie/001.avi,fun/movie/007.avi。若设定Prefix为 fun/,则返回三个Object;如果增加设定Delimiter为 /,则返回fun/test.jpg和fun/movie/ 。
// 参数的长度必须小于1024字节。使用Prefix查询时,返回的Key中仍会包含Prefix。
// marker
// 设定从Marker之后按字母排序开始返回Object。
// Marker用来实现分页显示效果,参数的长度必须小于1024字节。在做条件查询时,即使Marker在列表中不存在,也会从符合Marker字母排序的下一个开始打印。
// max-keys
// 指定返回Object的最大数。
// 取值:大于0小于1000,默认值:100。
// 如果因为Max-keys的设定无法一次完成列举,返回结果会附加一个<NextMarker>作为下一次列举的Marker。
try {
$ossClient = new OssClient('LTAI5tMJ1rbd6bmGxANvofqP', 'R26lxTP1TS5WpDgZnBpIcTgJWUsgCt', $this->endpoint);
$listObjectInfo = $ossClient->listObjects($bucket, $options);
} catch (OssException $e) {
$this->setError($e->getMessage());
return false;
}
$nlist['bucketName'] = $listObjectInfo->getBucketName();
$nlist['prefix'] = $listObjectInfo->getPrefix();
$nlist['marker'] = $listObjectInfo->getMarker();
$nlist['nextMarker'] = $listObjectInfo->getNextMarker();
$nlist['maxKeys'] = $listObjectInfo->getMaxKeys();
$nlist['delimiter'] = $listObjectInfo->getDelimiter();
$nlist['isTruncated'] = $listObjectInfo->getIsTruncated();
$nlist['objectList'] = array();
$nlist['prefixList'] = array();
$objectList = $listObjectInfo->getObjectList(); // object list
$prefixList = $listObjectInfo->getPrefixList(); // directory list
if (!empty($objectList)) {
foreach ($objectList as $objectInfo) {
$nlist['objectList'][] = $objectInfo->getKey();
}
}
if (!empty($prefixList)) {
foreach ($prefixList as $prefixInfo) {
$nlist['prefixList'][] = $prefixInfo->getPrefix();
}
}
return $nlist;
}
/**
* 下载文件到本地
* @param unknown $bucket 存储空间名称
* @param unknown $oss_save_path oss下文件路径及名称
* @param unknown $local_path 保存到本地路径
*/
public function downloadToLocal2($bucket, $oss_save_path, $local_path) {
$dir = dirname($local_path);
if(!is_dir($dir)) {
mkdir($dir, 0775, true);
chown($dir, 'nobody');
chgrp($dir, 'nobody');
}
$options = array(
OssClient::OSS_FILE_DOWNLOAD => $local_path
);
try{
$ossClient = new OssClient('LTAI5tMJ1rbd6bmGxANvofqP', 'R26lxTP1TS5WpDgZnBpIcTgJWUsgCt', $this->endpoint);
$ossClient->getObject($bucket, $oss_save_path, $options);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
return true;
}
public function isExist2($bucket, $object) {
try{
$ossClient = new OssClient('LTAI5tMJ1rbd6bmGxANvofqP', 'R26lxTP1TS5WpDgZnBpIcTgJWUsgCt', $this->endpoint);
$exist = $ossClient->doesObjectExist($bucket, $object);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
return $exist;
}
/**
* 删除单个文件
* @param unknown $bucket 存储空间名称
* @param unknown $oss_save_path oss下文件路径及名称 如abc/efg/123.jpg
* @return boolean
*/
public function delSingleFile2($bucket, $oss_save_path) {
try{
$ossClient = new OssClient('LTAI5tMJ1rbd6bmGxANvofqP', 'R26lxTP1TS5WpDgZnBpIcTgJWUsgCt', $this->endpoint);
$ossClient->deleteObject($bucket, $oss_save_path);
} catch(OssException $e) {
$this->setError($e->getMessage());
return false;
}
return true;
}
}