SAE saestorage.class.php文件的封装代码
Source for file saestorage.class.php Documentation is available at saestorage.class.php <?php
/**
* SAE数据存储服务
*
* @author quanjun
* @version $Id$
* @package sae
*
*/ /**
* SaeStorage class
* Storage服务适合用来存储用户上传的文件,比如头像、附件等。不适合存储代码类文件,比如页面内调用的JS、CSS等,尤其不适合存储追加写的日志。使用Storage服务来保存JS、CSS或者日志,会严重影响页面响应速度。建议JS、CSS直接保存到代码目录,日志使用sae_debug()方法记录。
*
* <code>
* <?php
* $s = new SaeStorage();
* $s->upload( 'example' , 'remote_file.txt' , 'local_file.txt' );
*
* echo $s->read( 'example' , 'thebook') ;
* // will echo 'bookcontent!';
*
* echo $s->getUrl( 'example' , 'thebook' );
* // will echo 'http://appname-example.stor.sinaapp.com/thebook';
*
* ?>
* </code>
*
* 常见错误码参考:
* - errno: 0 成功
* - errno: -2 配额统计错误
* - errno: -3 权限不足
* - errno: -7 Domain不存在
* - errno: -12 存储服务器返回错误
* - errno: -18 文件不存在
* - errno: -101 参数错误
* - errno: -102 存储服务器连接失败
* 注:可使用SaeStorage::errmsg()方法获得当前错误信息。
*
* @package sae
* @author quanjun
*
*/ class SaeStorage extends SaeObject
{
/**
* 用户accessKey
* @var string
*/
private $accessKey = '';
/**
* 用户secretKey
* @var string
*/
private $secretKey = '';
/**
* 运行过程中的错误信息
* @var string
*/
private $errMsg = 'success';
/**
* 运行过程中的错误代码
* @var int
*/
private $errNum = 0;
/**
* 应用名
* @var string
*/
private $appName = '';
/**
* @var string
*/
private $restUrl = '';
/**
* @var string
*/
private $filePath= '';
/**
* 文件URL主域名
* @var string
*/
private $basedomain = 'stor.sinaapp.com';
/**
* CDN URL主域名
* @var string
*/
private $cdndomain = 'sae.sinacdn.com';
/**
* 该类所支持的所有方法
* @var array
* @ignore
*/
protected $_optUrlList = array(
"uploadfile"=>'?act=uploadfile&ak=_AK_&sk=_SK_&dom=_DOMAIN_&attr=_ATTR_',
"getdomfilelist"=>'?act=getdomfilelist&ak=_AK_&sk=_SK_&dom=_DOMAIN_&prefix=_PREFIX_&limit=_LIMIT_&skip=_SKIP_',
"getfileattr"=>'?act=getfileattr&ak=_AK_&sk=_SK_&dom=_DOMAIN_&attrkey=_ATTRKEY_',
"getfilecontent"=>'?act=getfilecontent&ak=_AK_&sk=_SK_&dom=_DOMAIN_',
"delfile"=>'?act=delfile&ak=_AK_&sk=_SK_&dom=_DOMAIN_',
"delfolder"=>'?act=delfolder&ak=_AK_&sk=_SK_&dom=_DOMAIN_',
"getdomcapacity"=>'?act=getdomcapacity&ak=_AK_&sk=_SK_&dom=_DOMAIN_',
"setdomattr"=>'?act=setdomattr&ak=_AK_&sk=_SK_&dom=_DOMAIN_&attr=_ATTR_',
"setfileattr"=>'?act=setfileattr&ak=_AK_&sk=_SK_&dom=_DOMAIN_&attr=_ATTR_',
"getfilesnum"=>'?act=getfilesnum&ak=_AK_&sk=_SK_&dom=_DOMAIN_&path=_PATH_',
"getfileslist"=>'?act=getfileslist&ak=_AK_&sk=_SK_&dom=_DOMAIN_&path=_PATH_&limit=_LIMIT_&skip=_SKIP_&fold=_FOLD_',
);
/**
* 构造函数
* $_accessKey与$_secretKey可以为空,为空的情况下可以认为是公开读文件
* @param string $_accessKey
* @param string $_secretKey
* @return void
* @author Elmer Zhang
*/
public function __construct( $_accessKey='', $_secretKey='' )
{
if( $_accessKey== '' ) $_accessKey = SAE_ACCESSKEY;
if( $_secretKey== '' ) $_secretKey = SAE_SECRETKEY; $this->setAuth( $_accessKey, $_secretKey );
} /**
* 设置key
*
* 当需要访问其他APP的数据时使用
*
* @param string $akey
* @param string $skey
* @return void
* @author Elmer Zhang
* @ignore
*/
public function setAuth( $akey , $skey , $_appName = '' )
{
$this->initOptUrlList( $this->_optUrlList); if( $_appName == '') {
$this->appName = $_SERVER[ 'HTTP_APPNAME' ];
} else {
$this->appName = $_appName;
} $this->init( $akey, $skey );
} /**
* 返回运行过程中的错误信息
*
* @return string
* @author Elmer Zhang
*/
public function errmsg()
{
$ret = $this->errMsg." url(".$this->filePath.")";
$this->restUrl = '';
$this->errMsg = 'success!';
return $ret;
} /**
* 返回运行过程中的错误代码
*
* @return int
* @author Elmer Zhang
*/
public function errno()
{
$ret = $this->errNum;
$this->errNum = 0;
return $ret;
} /**
* 获取appname,供集成的类使用
*
* @return string
* @author lazypeople
*/
public function getAppname()
{
$ret = $this->appName;
return $ret;
} /**
* 取得通过CDN访问存储文件的url
*
* @param string $domain
* @param string $filename
* @return string
* @author Elmer Zhang
*/
public function getCDNUrl( $domain, $filename ) { // make it full domain
$domain = trim($domain);
$filename = $this->formatFilename($filename); if ( SAE_CDN_ENABLED ) {
$filePath = "http://".$this->appName.'.'.$this->cdndomain . "/.app-stor/$domain/$filename";
} else {
$domain = $this->getDom($domain);
$filePath = "http://".$domain.'.'.$this->basedomain . "/$filename";
}
return $filePath;
} /**
* 取得访问存储文件的url
*
* @param string $domain
* @param string $filename
* @return string
* @author Elmer Zhang
*/
public function getUrl( $domain, $filename ) { // make it full domain
$domain = trim($domain);
$filename = $this->formatFilename($filename);
$domain = $this->getDom($domain); $this->filePath = "http://".$domain.'.'.$this->basedomain . "/$filename";
return $this->filePath;
} private function setUrl( $domain , $filename )
{
$domain = trim($domain);
$filename = trim($filename); $this->filePath = "http://".$domain.'.'.$this->basedomain . "/$filename";
} /**
* 将数据写入存储
*
* 注意:文件名左侧所有的'/'都会被过滤掉。
*
* @param string $domain 存储域,在在线管理平台.storage页面可进行管理
* @param string $destFileName 文件名
* @param string $content 文件内容,支持二进制数据
* @param int $size 写入长度,默认为不限制
* @param array $attr 文件属性,可设置的属性请参考 SaeStorage::setFileAttr() 方法
* @param bool $compress 是否gzip压缩。如果设为true,则文件会经过gzip压缩后再存入Storage,常与$attr=array('encoding'=>'gzip')联合使用
* @return string 写入成功时返回该文件的下载地址,否则返回false
* @author Elmer Zhang
*/
public function write( $domain, $destFileName, $content, $size=-1, $attr=array(), $compress = false )
{
$domain = trim($domain);
$destFileName = $this->formatFilename($destFileName); if ( $domain == '' || $destFileName == '' )
{
$this->errMsg = 'the value of parameter (domain,destFileName,content) can not be empty!';
$this->errNum = -101;
return false;
} if ( $size > -1 )
$content = substr( $content, 0, $size ); $srcFileName = tempnam(SAE_TMP_PATH, 'SAE_STOR_UPLOAD');
if ($compress) {
file_put_contents("compress.zlib://" . $srcFileName, $content);
} else {
file_put_contents($srcFileName, $content);
} $re = $this->upload($domain, $destFileName, $srcFileName, $attr);
unlink($srcFileName);
return $re;
} /**
* 将文件上传入存储
*
* 注意:文件名左侧所有的'/'都会被过滤掉。
*
* @param string $domain 存储域,在在线管理平台.storage页面可进行管理
* @param string $destFileName 目标文件名
* @param string $srcFileName 源文件名
* @param array $attr 文件属性,可设置的属性请参考 SaeStorage::setFileAttr() 方法
* @param bool $compress 是否gzip压缩。如果设为true,则文件会经过gzip压缩后再存入Storage,常与$attr=array('encoding'=>'gzip')联合使用
* @return string 写入成功时返回该文件的下载地址,否则返回false
* @author Elmer Zhang
*/
public function upload( $domain, $destFileName, $srcFileName, $attr = array(), $compress = false )
{
$domain = trim($domain);
$destFileName = $this->formatFilename($destFileName); if ( $domain == '' || $destFileName == '' || $srcFileName == '' )
{
$this->errMsg = 'the value of parameter (domain,destFile,srcFileName) can not be empty!';
$this->errNum = -101;
return false;
} if ($compress) {
$srcFileNew = tempnam(SAE_TMP_PATH, 'SAE_STOR_UPLOAD');
file_put_contents("compress.zlib://" . $srcFileNew, file_get_contents($srcFileName));
$srcFileName = $srcFileNew;
} $domain = $this->getDom($domain);
$parseAttr = $this->parseFileAttr($attr); $this->setUrl( $domain, $destFileName ); $urlStr = $this->optUrlList['uploadfile'];
$urlStr = str_replace( '_DOMAIN_', $domain , $urlStr );
$urlStr = str_replace( '_ATTR_', urlencode(json_encode($parseAttr)), $urlStr );
$postData = array( 'srcFile' => "@{$srcFileName}" , 'destfile' => $destFileName);
$ret = $this->parseRetData( $this->getJsonContentsAndDecode( $urlStr, $postData ) );
if ( $ret !== false )
return $this->filePath;
else
return false;
} /**
* 获取指定domain下的文件名列表
*
* <code>
* <?php
* // 列出 Domain 下所有路径以photo开头的文件
* $stor = new SaeStorage();
*
* $num = 0;
* while ( $ret = $stor->getList("test", "photo", 100, $num ) ) {
* foreach($ret as $file) {
* echo "{$file}\n";
* $num ++;
* }
* }
*
* echo "\nTOTAL: {$num} files\n";
* ?>
* </code>
*
* @param string $domain 存储域,在在线管理平台.storage页面可进行管理
* @param string $prefix 路径前缀
* @param int $limit 返回条数,最大100条,默认10条
* @param int $offset 起始条数。limit与offset之和最大为10000,超过此范围无法列出。
* @return array 执行成功时返回文件列表数组,否则返回false
* @author Elmer Zhang
*/
public function getList( $domain, $prefix=NULL, $limit=10, $offset = 0 )
{
$domain = trim($domain); if ( $domain == '' )
{
$this->errMsg = 'the value of parameter (domain) can not be empty!';
$this->errNum = -101;
return false;
} $domain = $this->getDom($domain); $urlStr = $this->optUrlList['getdomfilelist'];
$urlStr = str_replace( '_DOMAIN_', $domain, $urlStr );
$urlStr = str_replace( '_PREFIX_', urlencode($prefix), $urlStr );
$urlStr = str_replace( '_LIMIT_', $limit, $urlStr );
$urlStr = str_replace( '_SKIP_', $offset, $urlStr ); return $this->parseRetData( $this->getJsonContentsAndDecode( $urlStr ) );
} /**
* 获取指定Domain、指定目录下的文件列表
*
* @param string $domain 存储域
* @param string $path 目录地址
* @param int $limit 单次返回数量限制,默认100,最大1000
* @param int $offset 起始条数
* @param int $fold 是否折叠目录
* @return array 执行成功时返回列表,否则返回false
* @author Elmer Zhang
*/
public function getListByPath( $domain, $path = NULL, $limit = 100, $offset = 0, $fold = true )
{
$domain = trim($domain); if ( $domain == '' )
{
$this->errMsg = 'the value of parameter (domain) can not be empty!';
$this->errNum = -101;
return false;
} $domain = $this->getDom($domain); $urlStr = $this->optUrlList['getfileslist'];
$urlStr = str_replace( '_DOMAIN_', $domain, $urlStr );
$urlStr = str_replace( '_PATH_', urlencode($path), $urlStr );
$urlStr = str_replace( '_LIMIT_', $limit, $urlStr );
$urlStr = str_replace( '_SKIP_', $offset, $urlStr );
$urlStr = str_replace( '_FOLD_', intval($fold), $urlStr ); return $this->parseRetData( $this->getJsonContentsAndDecode( $urlStr ) );
} /**
* 获取指定domain下的文件数量
*
*
* @param string $domain 存储域,在在线管理平台.storage页面可进行管理
* @param string $path 目录(暂不支持)
* @return array 执行成功时返回文件数,否则返回false
* @author Elmer Zhang
*/
public function getFilesNum( $domain, $path = NULL )
{
$domain = trim($domain); if ( $domain == '' )
{
$this->errMsg = 'the value of parameter (domain) can not be empty!';
$this->errNum = -101;
return false;
} $domain = $this->getDom($domain); $urlStr = $this->optUrlList['getfilesnum']; $urlStr = str_replace( '_DOMAIN_', $domain, $urlStr );
$urlStr = str_replace( '_PATH_', urlencode($path), $urlStr ); return $this->parseRetData( $this->getJsonContentsAndDecode( $urlStr ) );
} /**
* 获取文件属性
*
* @param string $domain 存储域
* @param string $filename 文件地址
* @param array $attrKey 属性值,如 array("fileName", "length"),当attrKey为空时,以关联数组方式返回该文件的所有属性。
* @return array 执行成功以数组方式返回文件属性,否则返回false
* @author Elmer Zhang
*/
public function getAttr( $domain, $filename, $attrKey=array() )
{
$domain = trim($domain);
$filename = $this->formatFilename($filename); if ( $domain == '' || $filename == '' )
{
$this->errMsg = 'the value of parameter (domain,filename) can not be empty!';
$this->errNum = -101;
return false;
} $domain = $this->getDom($domain); $this->setUrl( $domain, $filename ); $urlStr = $this->optUrlList['getfileattr'];
$urlStr = str_replace( '_DOMAIN_', $domain, $urlStr );
$urlStr = str_replace( '_ATTRKEY_', urlencode( json_encode( $attrKey ) ), $urlStr );
$postData = array( 'filename' => $filename);
$ret = $this->parseRetData( $this->getJsonContentsAndDecode( $urlStr, $postData ) );
if ( is_object( $ret ) )
return (array)$ret;
else
return $ret;
} /**
* 检查文件是否存在
*
* @param string $domain 存储域
* @param string $filename 文件地址
* @return bool
* @author Elmer Zhang
*/
public function fileExists( $domain, $filename )
{
$domain = trim($domain);
$filename = $this->formatFilename($filename); if ( $domain == '' || $filename == '' )
{
$this->errMsg = 'the value of parameter (domain,filename) can not be empty!';
$this->errNum = -101;
return false;
} if ( $this->getAttr( $domain, $filename, array('length') ) ) {
return true;
} else {
return false;
}
} /**
* 获取文件的内容
*
* @param string $domain
* @param string $filename
* @return string 成功时返回文件内容,否则返回false
* @author Elmer Zhang
*/
public function read( $domain, $filename )
{
$domain = trim($domain);
$filename = $this->formatFilename($filename); if ( $domain == '' || $filename == '' )
{
$this->errMsg = 'the value of parameter (domain,filename) can not be empty!';
$this->errNum = -101;
return false;
} $domain = $this->getDom($domain); $this->setUrl( $domain, $filename );
$urlStr = $this->optUrlList['getfilecontent'];
$urlStr = str_replace( '_DOMAIN_', $domain, $urlStr ); $postData = array( 'filename' => $filename);
$ret = $this->getJsonContentsAndDecode( $urlStr, $postData, false );
if ( is_array($ret) && isset( $ret['errno'] ) )
{
$this->parseRetData( $ret );
return false;
}
return $ret;
} /**
* 删除目录
*
* @param string $domain 存储域
* @param string $path 目录地址
* @return bool
* @author Elmer Zhang
* @ignore
*/
public function deleteFolder( $domain, $path )
{
$domain = trim($domain);
$path = $this->formatFilename($path); if ( $domain == '' || $path == '' )
{
$this->errMsg = 'the value of parameter (domain,path) can not be empty!';
$this->errNum = -101;
return false;
} $domain = $this->getDom($domain); $this->setUrl( $domain, $path );
$urlStr = $this->optUrlList['delfolder'];
$urlStr = str_replace( '_DOMAIN_', $domain, $urlStr );
$postData = array( 'path' => $path);
$ret = $this->parseRetData( $this->getJsonContentsAndDecode( $urlStr, $postData ) );
if ( $ret === false )
return false;
if ( $ret[ 'errno' ] == 0 )
return true;
else
return false;
} /**
* 删除文件
*
* @param string $domain
* @param string $filename
* @return bool
* @author Elmer Zhang
*/
public function delete( $domain, $filename )
{
$domain = trim($domain);
$filename = $this->formatFilename($filename); if ( $domain == '' || $filename == '' )
{
$this->errMsg = 'the value of parameter (domain,filename) can not be empty!';
$this->errNum = -101;
return false;
} $domain = $this->getDom($domain); $this->setUrl( $domain, $filename );
$urlStr = $this->optUrlList['delfile'];
$urlStr = str_replace( '_DOMAIN_', $domain, $urlStr );
$postData = array( 'filename' => $filename);
$ret = $this->parseRetData( $this->getJsonContentsAndDecode( $urlStr, $postData ) );
if ( $ret === false )
return false;
if ( $ret[ 'errno' ] == 0 )
return true;
else
return false;
} /**
* 设置文件属性
*
* 目前支持的文件属性
* - expires: 浏览器缓存超时,设置规则和domain expires的规则一致
* - encoding: 设置通过Web直接访问文件时,Header中的Content-Encoding。
* - type: 设置通过Web直接访问文件时,Header中的Content-Type。
* - private: 设置文件为私有,则文件不可被下载。
*
* <code>
* <?php
* $stor = new SaeStorage();
*
* $attr = array('expires' => 'modified 1y');
* $ret = $stor->setFileAttr("test", "test.txt", $attr);
* if ($ret === false) {
* var_dump($stor->errno(), $stor->errmsg());
* }
* ?>
* </code>
*
* @param string $domain
* @param string $filename 文件名
* @param array $attr 文件属性。格式:array('attr0'=>'value0', 'attr1'=>'value1', ......);
* @return bool
* @author Elmer Zhang
*/
public function setFileAttr( $domain, $filename, $attr = array() )
{
$domain = trim($domain);
$filename = $this->formatFilename($filename); if ( $domain == '' || $filename == '' )
{
$this->errMsg = 'the value of parameter domain,filename can not be empty!';
$this->errNum = -101;
return false;
} $parseAttr = $this->parseFileAttr($attr);
if ($parseAttr == false) {
$this->errMsg = 'the value of parameter attr must be an array, and can not be empty!';
$this->errNum = -101;
return false;
} $domain = $this->getDom($domain); $urlStr = $this->optUrlList['setfileattr'];
$urlStr = str_replace( '_DOMAIN_', $domain, $urlStr );
$urlStr = str_replace( '_ATTR_', urlencode( json_encode( $parseAttr ) ), $urlStr );
$postData = array( 'filename' => $filename);
$ret = $this->parseRetData( $this->getJsonContentsAndDecode( $urlStr, $postData ) );
if ( $ret === true )
return true;
if ( is_array($ret) && $ret[ 'errno' ] === 0 )
return true;
else
return false;
} /**
* 设置Domain属性
*
* 目前支持的Domain属性
* - expires: 浏览器缓存超时
* - expires_type: 浏览器对于指定文件类型的缓存超时
* - allowReferer: 根据Referer防盗链
* - private: 是否私有Domain
* - 404Redirect: 404跳转页面,只能是本应用页面,或本应用Storage中文件。例如http://appname.sinaapp.com/404.html或http://appname-domain.stor.sinaapp.com/404.png
* - tag: Domain简介。格式:array('tag1', 'tag2')
* <code>
* <?php
* // 缓存过期设置
* $expires = 'modified 1d';
* $expires_type = 'text/html 48h,image/png modified 1y';
*
* // 防盗链设置
* $allowReferer = array();
* $allowReferer['hosts'][] = '*.elmerzhang.com'; // 允许访问的来源域名,千万不要带 http://。支持通配符*和?
* $allowReferer['hosts'][] = 'elmer.sinaapp.com';
* $allowReferer['hosts'][] = '?.elmer.sinaapp.com';
* $allowReferer['redirect'] = 'http://elmer.sinaapp.com/'; // 盗链时跳转到的地址,仅允许跳转到本APP的页面,且不可使用独立域名。如果不设置或者设置错误,则直接拒绝访问。
* //$allowReferer = false; // 如果要关闭一个Domain的防盗链功能,直接将allowReferer设置为false即可
*
* $stor = new SaeStorage();
*
* $attr = array('expires'=>$expires,'expires_type'=>$expires_type,'allowReferer'=>$allowReferer);
* $ret = $stor->setDomainAttr("test", $attr);
* if ($ret === false) {
* var_dump($stor->errno(), $stor->errmsg());
* }
*
* ?>
* </code>
*
* @param string $domain
* @param array $attr Domain属性。格式:array('attr0'=>'value0', 'attr1'=>'value1', ......);
* 说明:
* - expires 格式:[modified] TIME_DELTA,例如modified 1y或者1y,modified关键字用于指定expire时间相对于文件的修改时间。默认expire时间是相对于access time。如果TIME_DELTA为负, Cache-Control header会被设置为no-cache。
* - TIME_DELTA,TIME_DELTA是一个表示时间的字符串,例如: 1y3M 48d 5s
* <pre>
* s seconds
* ----------------------------------------------------------
* m minutes
* ----------------------------------------------------------
* h hours
* ----------------------------------------------------------
* d days
* ----------------------------------------------------------
* w weeks
* ----------------------------------------------------------
* M months, 30 days
* ----------------------------------------------------------
* y years, 365 days
* ----------------------------------------------------------
* </pre>
* - 两个特殊的TIME_DELTA:<pre>
* epoch sets the Expires header to 1 January, 1970 00:00:01 GMT.
* -----------------------------------------------------------------------------------------------
* max sets the Expires header to 31 December 2037 23:59:59 GMT, and the Cache-Control max-age to 10 years.
* -----------------------------------------------------------------------------------------------
* </pre>
* - expires_type 格式:TYPE [modified] TIME_DELTA,TYPE为文件的mimetype,例如text/html, text/plain, image/gif。多条expires-type规则之间以 , 隔开。例如:text/html 48h,image/png modified 1y
* @return bool
* @author Elmer Zhang,Lazypeople
*/
public function setDomainAttr( $domain, $attr = array() )
{
$domain = trim($domain); if ( $domain == '' )
{
$this->errMsg = 'the value of parameter domain can not be empty!';
$this->errNum = -101;
return false;
} // make it full domain
$domain = $this->getDom($domain); $parseAttr = $this->parseDomainAttr($attr); if ($parseAttr == false) {
$this->errMsg = 'the value of parameter attr must be an array, and can not be empty!';
$this->errNum = -101;
return false;
} $urlStr = $this->optUrlList['setdomattr'];
$urlStr = str_replace( '_DOMAIN_', $domain, $urlStr );
$urlStr = str_replace( '_ATTR_', urlencode( json_encode( $parseAttr ) ), $urlStr );
$ret = $this->parseRetData( $this->getJsonContentsAndDecode( $urlStr ) );
if ( $ret === true )
return true;
if ( is_array($ret) && $ret['errno'] === 0 )
return true;
else
return false;
} /**
* 获取domain所占存储的大小
*
* @param string $domain
* @return int
* @author Elmer Zhang
*/
public function getDomainCapacity( $domain )
{
$domain = trim($domain); if ( $domain == '' )
{
$this->errMsg = 'the value of parameter \'$domain\' can not be empty!';
$this->errNum = -101;
return false;
} $domain = $this->getDom($domain); $urlStr = $this->optUrlList['getdomcapacity'];
$urlStr = str_replace( '_DOMAIN_', $domain, $urlStr );
$ret = (array)$this->parseRetData( $this->getJsonContentsAndDecode( $urlStr ) );
if ( $ret[ 'errno' ] == 0 )
return $ret['data'];
else
return false;
} // ================================================================= /**
* @ignore
*/
protected function parseDomainAttr($attr) {
$parseAttr = array(); if ( !is_array( $attr ) || empty( $attr ) ) {
return false;
} foreach ( $attr as $k => $a ) {
switch ( strtolower( $k ) ) {
case '404redirect':
if ( !empty($a) && is_string($a) ) {
$parseAttr['404Redirect'] = trim($a);
}
break;
case 'private':
$parseAttr['private'] = $a ? true : false;
break;
case 'expires':
$parseAttr['expires'] = $a;
break;
case 'expires_type':
$parseAttr['expires_type'] = $a;
break;
case 'allowreferer':
if ( isset($a['hosts']) && is_array($a['hosts']) && !empty($a['hosts']) ) {
$parseAttr['allowReferer'] = array();
$parseAttr['allowReferer']['hosts'] = $a['hosts']; if ( isset($a['redirect']) && is_string($a['redirect']) ) {
$parseAttr['allowReferer']['redirect'] = $a['redirect'];
}
} else {
$parseAttr['allowReferer']['host'] = false;
}
break;
case 'tag':
if (is_array($a) && !empty($a)) {
$parseAttr['tag'] = array();
foreach ($a as $v) {
$v = trim($v);
if (is_string($v) && !empty($v)) {
$parseAttr['tag'][] = $v;
}
}
}
break;
default:
break;
}
} return $parseAttr;
} /**
* @ignore
*/
protected function parseFileAttr($attr) {
$parseAttr = array(); if ( !is_array( $attr ) || empty( $attr ) ) {
return false;
} foreach ( $attr as $k => $a ) {
switch ( strtolower( $k ) ) {
case 'expires':
$parseAttr['expires'] = $a;
break;
case 'encoding':
$parseAttr['encoding'] = $a;
break;
case 'type':
$parseAttr['type'] = $a;
break;
case 'private':
$parseAttr['private'] = intval($a);
break;
default:
break;
}
} return $parseAttr;
} /**
* @ignore
*/
protected function initOptUrlList( $_optUrlList=array() )
{
$this->optUrlList = array();
$this->optUrlList = $_optUrlList; while ( current( $this->optUrlList ) !== false ) {
$this->optUrlList[ key( $this->optUrlList ) ] = SAE_STOREHOST.current($this->optUrlList);
next( $this->optUrlList );
} reset( $this->optUrlList );
//$this->init( $this->accessKey, $this->secretKey ); }
/**
* 构造函数运行时替换所有$this->optUrlList值里的accessKey与secretKey
* @param string $_accessKey
* @param string $_secretKey
* @return void
* @ignore
*/
protected function init( $_accessKey, $_secretKey )
{
$_accessKey = trim($_accessKey);
$_secretKey = trim($_secretKey); //$this->appName = $_SERVER[ 'HTTP_APPNAME' ];
$this->accessKey = $_accessKey;
$this->secretKey = $_secretKey;
while ( current( $this->optUrlList ) !== false )
{
$this->optUrlList[ key( $this->optUrlList ) ] = str_replace( '_AK_', $this->accessKey, current( $this->optUrlList ) );
$this->optUrlList[ key( $this->optUrlList ) ]= str_replace( '_SK_', $this->secretKey, current( $this->optUrlList ) );
next( $this->optUrlList );
} reset( $this->optUrlList );
} /**
* 最终调用server端方法的rest函数封装
* @ignore
*/
protected function getJsonContentsAndDecode( $url, $postData = array(), $decode = true ) //获取对应URL的JSON格式数据并解码
{
if( empty( $url ) )
return false;
$this->restUrl = $url;
$ch=curl_init(); curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_HTTPGET, true );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); if ( !Empty( $postData ) )
{
curl_setopt($ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $postData );
} curl_setopt( $ch, CURLOPT_USERAGENT, 'SAE Online Platform' );
$content=curl_exec( $ch );
$info = curl_getinfo($ch);
//var_dump($content, $info);
curl_close($ch);
if( false !== $content )
{
if ($decode) {
$tmp = json_decode( $content , true); if ( !empty( $tmp ) )//若非结构数据则直接抛出数据源
return $tmp;
}
return $content;
}
else
return array( 'errno'=>-102, 'errmsg'=>'bad request' );
} /**
* 解析并验证server端返回的数据结构
* @ignore
*/
public function parseRetData( $retData = array() )
{
// print_r( $retData );
if ( !isset( $retData['errno'] ) || !isset( $retData['errmsg'] ) )
{
// print_r( $retData );
$this->errMsg = 'bad request';
$this->errNum = -12;
return false;
}
if ( $retData['errno'] !== 0 )
{
$this->errMsg = $retData[ 'errmsg' ];
$this->errNum = $retData['errno'];
return false;
}
if ( isset( $retData['data'] ) )
return $retData['data'];
return $retData;
} /**
* domain拼接
* @param string $domain
* @param bool $concat
* @return string
* @author Elmer Zhang
* @ignore
*/
protected function getDom($domain, $concat = true) {
$domain = strtolower(trim($domain)); if ($concat) {
if( strpos($domain, '-') === false ) {
$domain = $this->appName .'-'. $domain;
}
} else {
if ( ( $pos = strpos($domain, '-') ) !== false ) {
$domain = substr($domain, $pos + 1);
}
}
return $domain;
} private function formatFilename($filename) {
$filename = trim($filename); $encodings = array( 'UTF-8', 'GBK', 'BIG5' ); $charset = mb_detect_encoding( $filename , $encodings);
if ( $charset !='UTF-8' ) {
$filename = mb_convert_encoding( $filename, "UTF-8", $charset);
} $filename = preg_replace('/\/\.\//', '/', $filename);
$filename = ltrim($filename, '/');
$filename = preg_replace('/^\.\//', '', $filename);
while ( preg_match('/\/\//', $filename) ) {
$filename = preg_replace('/\/\//', '/', $filename);
} return $filename;
}
}
Documentation generated on Tue, 25 Feb 2014 21:24:49 +0800 by phpDocumentor 1.4.3
重要的部分已经有注释,有时间在吧全部代码注释起来
SAE saestorage.class.php文件的封装代码的更多相关文章
- SAE java应用读写文件(TmpFS和Storage)-----绝世好代码
近期不少java用户都在提sae读写本地文件的问题,在这里结合TmpFS和Storage服务说说java应用应该如何读写文件TmpFS是一个供应用临时读写的路径,但请求过后将被销毁.出于安全考虑,sa ...
- python解析xml模块封装代码
在python中解析xml文件的模块用法,以及对模块封装的方法.原文转自:http://www.jbxue.com/article/16586.html 有如下的xml文件:<?xml vers ...
- 将DLL文件直接封装进exe执行文件中(C#)
前言:由于项目需要,需制作一个注册机,将个人PC的MAC值和硬盘序列号与软件进行绑定,由于笔者的C++不是很好,所以采用C#进行开发.但在采用C#的时候,获取硬盘的MAC值和序列号的时候又不是很准确, ...
- SAE java应用读写文件(TmpFS和Storage)
近期不少java用户都在提sae读写本地文件的问题,在这里结合TmpFS和Storage服务说说java应用应该如何读写文件TmpFS是一个供应用临时读写的路径,但请求过后将被销毁.出于安全考虑,sa ...
- Java关于条件判断练习--统计一个src文件下的所有.java文件内的代码行数(注释行、空白行不统计在内)
要求:统计一个src文件下的所有.java文件内的代码行数(注释行.空白行不统计在内) 分析:先封装一个静态方法用于统计确定的.java文件的有效代码行数.使用字符缓冲流读取文件,首先判断是否是块注释 ...
- PHP 文件限速下载代码
php 文件限速下载代码 <?php include("DBDA.class.php"); $db = new DBDA(); $bs = $_SERVER["QU ...
- C#各种文件操作的代码与注释
C#各种文件操作的代码与注释,具体看下面代码: using System; using System.Collections.Generic; using System.Linq; using Sys ...
- 【原】Mac下统计任意文件夹中代码行数的工具——cloc
这里介绍一个Mac系统统计代码行数的工具cloc. 1.首先,安装homebrew,已安装的请跳过. 打开终端工具Terminal,输入下列命令.过程中会让你按RETURN键以及输入mac桌面密码,按 ...
- webservice 服务端例子+客户端例子+CXF整合spring服务端测试+生成wsdl文件 +cxf客户端代码自动生成
首先到CXF官网及spring官网下载相关jar架包,这个不多说.webservice是干嘛用的也不多说. 入门例子 模拟新增一个用户,并返回新增结果,成功还是失败. 大概的目录如上,很简单. Res ...
随机推荐
- svn 日志版本回滚
[root@v01 online]# svn diff -r 9:8 Index: index.html =============================================== ...
- LeetCode之Min Stack 实现最小栈
LeetCode相关的网上资源比较多,看到题目一定要自己做一遍,然后去学习参考其他的解法. 链接: https://oj.leetcode.com/problems/min-stack/ 题目描述: ...
- Spring MVC笔记 使用JdbcTemplate
Spring提供了 JdbcTemplate 来封装数据库jdbc操作细节, 包括: 数据库连接[打开/关闭] ,异常转义 ,SQL执行 ,查询结果的转换, 其中体现了 模板模式 的设计模式思想. 使 ...
- CDT
Eclipse CDT 是 Eclipse 插件,它将把 Eclipse 转换为功能强大的 C/C++ IDE.
- ☆☆配置NDK环境
1 前提是 已经配置好 安卓SDK开发环境. 2 下载 android-ndk64-r10-windows-x86_64,可以从官方网站下载,这里有一个现成的. http://pan.baidu.co ...
- C++的那些事:表达式与语句
表达式 1,应该把函数调用当作是一种运算符,这种运算符对参与运算的对象没有数量限制. 2,关于“左值(lvalue)”和“右值(rvalue)”可以做一个简单的归纳:当一个对象被用作右值的时候,用的是 ...
- Ajax介绍
AJAX AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现有标准的新方法. AJA ...
- poj 1114 完全背包 dp
如果可以每个物品拿多件,则从小到大遍历,否则从大到小遍历. G - Piggy-Bank Time Limit:1000MS Memory Limit:32768KB 64bit IO ...
- SU Demos-02Filtering-04Sugabor
进入目录后,先看readme, 生成数据, 显示结果, 用其他软件打开,查看原始数据, 这是数据的全貌,
- WPF MVVM模式下的无阻塞刷新探讨
很多时候我们需要做一个工作,在一个方法体里面,读取大数据绑定到UI界面,由于长时间的读取,读取独占了线程域,导致界面一直处于假死状态.例如,当应用程序开始读取Web资源时,读取的时效是由网络链路的速度 ...