Source for file saestorage.class.php

Documentation is available at saestorage.class.php

  1. <?php
  2. /**
  3.  * This is the PHP SDK API For SAE Storage Service.
  4.  *
  5.  *
  6.  * See COPYING for license information.
  7.  *
  8.  * @author lazypeople
  9.  * @copyright Copyright (c) 2013, Sina App Engine.
  10.  * @package sae
  11.  */
  12.  
  13. include_once dirname(__FILE__'/swiftclient.php';
  14.  
  15. class SaeStorage extends SaeObject 
  16. {
  17.     private $accessKey  '';
  18.     private $secretKey  '';
  19.     private $errMsg     'success';
  20.     private $errNum     0;
  21.     private $appName    '';
  22.     private $restUrl    '';
  23.     private $filePath   '';
  24.     private $basedomain 'stor.sinaapp.com';
  25.     private $cdndomain  'sae.sinacdn.com';
  26.     protected $swift_conn;
  27.     
  28.     /**
  29.      * Class constructor
  30.      *
  31.      * @param string $accessKey AccessKey of Appname
  32.      * @param string $secretKey SecretKey of Appname
  33.      */
  34.     function __construct($accessKey NULL$secretKey NULL)
  35.     {
  36.  
  37.         if (empty($accessKey)) {
  38.             $this->accessKey SAE_ACCESSKEY;
  39.         else {
  40.             $this->accessKey $accessKey;
  41.         }
  42.         if (empty($secretKey)) {
  43.             $this->secretKey SAE_SECRETKEY;
  44.         else {
  45.             $this->secretKey $secretKey;
  46.         }
  47.         $this->appName $_SERVER'HTTP_APPNAME' ];
  48.         $this->swift_conn = new CF_Connection($this->accessKey,$this->secretKey,$this->appName);
  49.     }
  50.  
  51.     /**
  52.      * 跨应用授权访问
  53.      *
  54.      * 当需要访问其他APP的数据时使用
  55.      *
  56.      * @param string $akey,应用的accessKey 
  57.      * @param string $skey,应用的secretKey 
  58.      * @param string _appName, 应用名
  59.      * @return void 
  60.      * @ignore
  61.      */
  62.     public function setAuth$akey $skey $_appName '' )
  63.     {
  64.         if$_appName == ''{
  65.             $this->appName $_SERVER'HTTP_APPNAME' ];
  66.         else {
  67.             $this->appName $_appName;
  68.         }
  69.         $this->accessKey $akey;
  70.         $this->secretKey $skey;
  71.         $this->swift_conn = new CF_Connection($this->accessKey,$this->secretKey,$this->appName);
  72.     }
  73.  
  74.  
  75.  
  76.     /**
  77.      * 获取错误信息
  78.      * 
  79.      * @desc
  80.      * 
  81.      * @access public
  82.      * @return void 
  83.      * @exception none
  84.      */
  85.     public function errmsg()
  86.     {
  87.         $ret $this->errMsg." url(".$this->filePath.")";
  88.         $this->restUrl '';
  89.         $this->errMsg 'Success';
  90.         return $ret;
  91.     }
  92.  
  93.     /**
  94.      * 获取错误码
  95.      * 
  96.      * @desc
  97.      * 
  98.      * @access public
  99.      * @return void 
  100.      * @exception none
  101.      */
  102.     public function errno()
  103.     {
  104.         $ret $this->errNum;
  105.         $this->errNum 0;
  106.         return $ret;
  107.     }
  108.  
  109.  
  110.     /**
  111.      * 获取当前正在操作的应用名
  112.      * 
  113.      * @desc
  114.      * 
  115.      * @access public
  116.      * @return void 
  117.      * @exception none
  118.      * @ignore
  119.      */
  120.     public function getAppname()
  121.     {
  122.         return $this->appName;
  123.     }
  124.  
  125.     /**
  126.      * 获取文件CDN 地址
  127.      *
  128.      * Example:
  129.      * <code>
  130.      * #Get a CDN url
  131.      * $stor = new SaeStorage();
  132.      * $cdn_url = $stor->getCDNUrl("domain","cdn_test.txt");
  133.      * </code>
  134.      *
  135.      * @param string $domain Domain name
  136.      * @param string $filename Filename you save
  137.      * @return string. 
  138.      */
  139.     public function getCDNUrl$domain$filename 
  140.     {
  141.         $domain strtolower(trim($domain));
  142.         $filename $this->formatFilename($filename);
  143.  
  144.         if SAE_CDN_ENABLED {
  145.             $filePath "http://".$this->appName.'.'.$this->cdndomain "/.app-stor/$domain/$filename";
  146.         else {
  147.             $domain $this->getDom($domain);
  148.             $filePath "http://".$domain.'.'.$this->basedomain "/$filename";
  149.         }
  150.         return $filePath;
  151.     }
  152.  
  153.     /**
  154.      * 获取文件storage访问地址
  155.      *
  156.      * Example:
  157.      * <code>
  158.      * #Get the url of a stored file
  159.      * $stor = new SaeStorage();
  160.      * $file_url = $stor->getUrl("domain","cdn_test.txt");
  161.      * </code>
  162.      *
  163.      * @param string $domain Domain name
  164.      * @param string $filename Filename you save
  165.      * @return string. 
  166.      */
  167.     public function getUrl$domain$filename 
  168.     {
  169.         $domain strtolower(trim($domain));
  170.         $filename $this->formatFilename($filename);
  171.         $domain $this->getDom($domain);
  172.  
  173.         $this->filePath "http://".$domain.'.'.$this->basedomain "/$filename";
  174.         return $this->filePath;
  175.     }
  176.  
  177.     /**
  178.      * Set File url.
  179.      *
  180.      * @param string $domain 
  181.      * @param string $filename The filename you wanna set
  182.      * @return string. 
  183.      * @ignore
  184.      */
  185.     private function setUrl$domain $filename )
  186.     {
  187.         $domain strtolower(trim($domain));
  188.         $filename $this->formatFilename($filename);
  189.         $this->filePath "http://".$domain.'.'.$this->basedomain "/$filename";
  190.     }
  191.  
  192.  
  193.      /**
  194.      * 将数据写入存储
  195.      *
  196.      * Example:
  197.      * <code>
  198.      * # Write some content into a storage file
  199.      * #
  200.      * $storage = new SaeStorage();
  201.      * $domain = 'domain';
  202.      * $destFileName = 'write_test.txt';
  203.      * $content = 'Hello,I am from the method of write'
  204.      * $attr = array('encoding'=>'gzip');
  205.      * $result = $storage->write($domain,$destFileName, $content, -1, $attr, true);
  206.      *
  207.      * </code>
  208.      *
  209.      *
  210.      * @param string $domain Domain name
  211.      * @param string $destFileName The destiny fileName.
  212.      * @param string $content The content of the file
  213.      * @param int    $size The length of file content,the overflower will be truncated and by default there is no limit.
  214.      * @param array  $attr File attributes, set attributes refer to SaeStorage :: setFileAttr () method
  215.      * @param boolean $compress 
  216.      *  #Note: Whether gzip compression.
  217.      *         If true, the file after gzip compression and then stored in Storage,
  218.      *         often associated with $attr=array('encoding'=>'gzip') used in conjunction
  219.      * @return mixed 
  220.      *  #Note: If success,return the url of the file
  221.      *         If faild;return false
  222.      */
  223.     public function write$domain$destFileName$content$size = -1$attr array()$compress false )
  224.     {
  225.         $domain $this->parseDomain(trim($domain));
  226.         $destFileName $this->formatFilename($destFileName);
  227.  
  228.         if (empty($domainor empty($destFileName)) {
  229.             $this->errMsg 'The value of parameter (domain,destFileName,content) can not be empty!';
  230.             $this->errNum = -101;
  231.             return false;
  232.         }
  233.  
  234.         if $size > -)
  235.             $content substr$content0$size );
  236.  
  237.         $srcFileName tempnam(SAE_TMP_PATH'SAE_STOR_UPLOAD');
  238.         if ($compress{
  239.             file_put_contents("compress.zlib://" $srcFileName$content);
  240.         else {
  241.             file_put_contents($srcFileName$content);
  242.         }
  243.  
  244.         $re $this->upload($domain$destFileName$srcFileName$attr);
  245.         unlink($srcFileName);
  246.         return $re;
  247.     }
  248.  
  249.     /**
  250.      * 将文件上传入存储
  251.      *
  252.      * Example:
  253.      * <code>
  254.      * #
  255.      * $storage = new SaeStorage();
  256.      * $domain = 'domain';
  257.      * $destFileName = 'write_test.txt';
  258.      * $srcFileName = $_FILE['tmp_name']
  259.      * $attr = array('encoding'=>'gzip');
  260.      * $result = $storage->upload($domain,$destFileName, $srcFileName, -1, $attr, true);
  261.      *
  262.      * </code>
  263.      *
  264.      * The `domain` must be Exist
  265.      *
  266.      * @param string $domain Domain name
  267.      * @param string $destFileName The destiny fileName.
  268.      * @param string $srcFileName The source of the uoload file
  269.      * @param array  $attr File attributes, set attributes refer to SaeStorage :: setFileAttr () method
  270.      * @param boolean $compress 
  271.      *  #Note: Whether gzip compression.
  272.      *         If true, the file after gzip compression and then stored in Storage,
  273.      *         often associated with $attr=array('encoding'=>'gzip') used in conjunction
  274.      * @return mixed 
  275.      *  #Note: If success,return the url of the file
  276.      *         If faild;return false
  277.      */
  278.     public function upload$domain$destFileName$srcFileName$attr array()$compress false )
  279.     {
  280.         $domain $this->parseDomain(trim($domain));
  281.         $destFileName $this->formatFilename($destFileName);
  282.  
  283.         if empty($domainor empty($destFileNameor empty($srcFileName)) {
  284.             $this->errMsg 'The value of parameter (domain,destFile,srcFileName) can not be empty!';
  285.             $this->errNum = -101;
  286.             return false;
  287.         }
  288.  
  289.         if ($compress{
  290.             $srcFileNew tempnamSAE_TMP_PATH'SAE_STOR_UPLOAD');
  291.             file_put_contents("compress.zlib://" $srcFileNewfile_get_contents($srcFileName));
  292.             $srcFileName $srcFileNew;
  293.         }
  294.         $parseAttr $this->parseFileAttr($attr);
  295.         $this->setUrl$this->getDom($domain)$destFileName );
  296.  
  297.         try {
  298.             $container $this->swift_conn->get_container($domain);
  299.         catch (Exception $e{
  300.             $this->errMsg $e->getMessage();
  301.             $this->errNum = -122;
  302.             return false;
  303.         }
  304.         
  305.         try {
  306.             $object $container->create_object($destFileName);
  307.             $object->__getMimeType($destFileName);
  308.         catch (Exception $e{
  309.             $this->errMsg $e->getMessage();
  310.             $this->errNum = -123;
  311.             return false;
  312.         }
  313.         
  314.         try {
  315.             $result $object->load_from_filename($srcFileName);
  316.             if (count($attr)) {
  317.                 $this->setFileAttr($domain,$destFileName,$attr);
  318.             }
  319.             return $this->getUrl($domain,$destFileName);
  320.         catch (Exception $e{
  321.             $this->errMsg sprintf('Failed to store to filesystem!(%s)',$e->getMessage());
  322.             $this->errNum 121;
  323.             return false;
  324.         }
  325.     }
  326.  
  327.     /**
  328.      * 获取指定domain下的文件名列表
  329.      *
  330.      * <code>
  331.      * <?php
  332.      * // 列出 Domain 下所有路径以photo开头的文件
  333.      * $stor = new SaeStorage();
  334.      *
  335.      * $num = 0;
  336.      * while ( $ret = $stor->getList("test", "photo", 100, $num ) ) {
  337.      *      foreach($ret as $file) {
  338.      *          echo "{$file}\n";
  339.      *          $num ++;
  340.      *      }
  341.      * }
  342.      * 
  343.      * echo "\nTOTAL: {$num} files\n";
  344.      * ?>
  345.      * </code>
  346.      *
  347.      * @param string $domain    存储域,在在线管理平台.storage页面可进行管理
  348.      * @param string $prefix    路径前缀
  349.      * @param int $limit        返回条数,最大100条,默认10条
  350.      * @param int $offset       起始条数。limit与offset之和最大为10000,超过此范围无法列出。
  351.      * @return array 执行成功时返回文件列表数组,否则返回false
  352.      */
  353.     public function getList$domain$prefix=NULL$limit=10$offset )
  354.     {
  355.         $domain $this->parseDomain(trim($domain));
  356.         $limit += $offset;
  357.  
  358.         if $domain == '' {
  359.             $this->errMsg 'The value of parameter (domain) can not be empty!';
  360.             $this->errNum = -101;
  361.             return false;
  362.         }
  363.  
  364.         try {
  365.             $container $this->swift_conn->get_container($domain);
  366.         catch (Exception $e{
  367.             $this->errMsg $e->getMessage();
  368.             $this->errNum = -122;
  369.             return false;
  370.         }
  371.  
  372.         try {
  373.             $list_detail $container->get_objects($limit,NULL,$prefix);
  374.             $list_detail_array $this->std_class_object_to_array($list_detail);
  375.             $list_detail_new array();
  376.             foreach($list_detail_array as $small{
  377.                 $list_detail_new[$small['name']
  378.             }
  379.             $total_num count($list_detail_new);
  380.             $file_list array();
  381.             if $total_num $offset return array();
  382.             for $i $offset$i $total_num$i++{
  383.                 $file_list[$list_detail_new[$i];
  384.             }
  385.             return $file_list;
  386.         catch (Exception $e{
  387.             $this->errMsg $e->getMessage();
  388.             $this->errNum = -110;
  389.             return false;
  390.         }
  391.     }
  392.  
  393.     /**
  394.      * 获取指定Domain、指定目录下的文件列表
  395.      *
  396.      * @param string $domain    存储域
  397.      * @param string $path      目录地址
  398.      * @param int $limit        单次返回数量限制,默认100,最大1000
  399.      * @param int $offset       起始条数
  400.      * @param int $fold         是否折叠目录
  401.      * @return array 执行成功时返回列表,否则返回false
  402.      */
  403.     public function getListByPath$domain$path NULL$limit 100$offset 0$fold true )
  404.     {
  405.         setlocale(LC_ALL'en_US.UTF8');
  406.         $limit += $offset;
  407.         $domain $this->parseDomain(trim($domain));
  408.  
  409.         if $domain == '' {
  410.             $this->errMsg 'the value of parameter (domain) can not be empty!';
  411.             $this->errNum = -101;
  412.             return false;
  413.         }
  414.  
  415.         try {
  416.             $container $this->swift_conn->get_container($domain);
  417.         catch (Exception $e{
  418.             $this->errMsg $e->getMessage();
  419.             $this->errNum = -122;
  420.             return false;
  421.         }
  422.  
  423.         if($fold{
  424.             $delimiter '/';
  425.         else {
  426.             $delimiter NULL;
  427.         }
  428.  
  429.         try {
  430.             if($path != ''){$path $path."/";}
  431.             $result $container->get_objects($limit,NULL,$path,NULL,$delimiter,true);
  432.             $file_list array();
  433.             $total_num count($result);
  434.             if $total_num $offset return array();
  435.             for $i $offset$i $total_num$i++{
  436.                 $file_list[$result[$i];
  437.             }
  438.             $result $file_list;
  439.             if ($fold{
  440.                 $list['dirNum'0;
  441.                 $list['fileNum'0;
  442.                 $list['dirs'array();
  443.                 $list['files'array();
  444.                 foreach $result as $item {
  445.                     if isset$item['subdir') ) {
  446.                         $list['dirs'][array(
  447.                             'name' => basename($item['subdir']),
  448.                             'fullName' => $item['subdir']
  449.                             );
  450.                         $list['dirNum'++;
  451.                     else {
  452.                         $file array(
  453.                             'Name' => basename($item['name']),
  454.                             'fullName' => $item['name'],
  455.                             'length' => $item['bytes'],
  456.                             'uploadTime' => strtotime($item['last_modified']60 60 8
  457.                             );
  458.                         if isset($item['X-Sws-Object-Meta-Expires-Rule']) ) $file['expires'$headers['X-Sws-Object-Meta-Expires-Rule'];
  459.                         $list['files'][$file;
  460.                         $list['fileNum'++;
  461.                     }
  462.                 }
  463.             else {
  464.                 $list array();
  465.                 foreach $result as $item {
  466.                     $list[array(
  467.                         'Name' => basename($item['name']),
  468.                         'fullName' => $item['name'],
  469.                         'length' => $item['bytes'],
  470.                         'uploadTime' => strtotime($item['last_modified'])
  471.                         );
  472.                 }
  473.             }
  474.             return $list;
  475.         catch (Exception $e{
  476.             $this->errMsg $e->getMessage();
  477.             $this->errNum = -113;
  478.             return false;
  479.         }               
  480.     }
  481.  
  482.     /**
  483.      * 获取指定domain下的文件数量
  484.      *
  485.      *
  486.      * @param string $domain    存储域,在在线管理平台.storage页面可进行管理
  487.      * @param string $path      目录(暂没实现)
  488.      * @return array 执行成功时返回文件数,否则返回false
  489.      */
  490.     public function getFilesNum$domain$path NULL )
  491.     {
  492.         $domain $this->parseDomain(trim($domain));
  493.  
  494.         if $domain == '' {
  495.             $this->errMsg 'the value of parameter (domain) can not be empty!';
  496.             $this->errNum = -101;
  497.             return false;
  498.         }
  499.         try {
  500.             $info $this->swift_conn->get_container($domain);
  501.             $info_array $this->std_class_object_to_array($info);
  502.             return $info_array['object_count']
  503.         catch (Exception $e{
  504.             $this->errMsg $e->getMessage();
  505.             $this->errNum = -114;
  506.             return false;
  507.         }        
  508.     }
  509.  
  510.     /**
  511.      * 获取文件属性
  512.      *
  513.      * @param string $domain    存储域
  514.      * @param string $filename  文件地址
  515.      * @param array  $attrKey    属性值,如 array("fileName", "length"),当attrKey为空时,以关联数组方式返回该文件的所有属性。
  516.      * @return array 执行成功以数组方式返回文件属性,否则返回false
  517.      */
  518.     public function getAttr$domain$filename$attrKey=array() )
  519.     {
  520.         $domain $this->parseDomain(trim($domain));
  521.         $filename $this->formatFilename($filename);
  522.  
  523.         if $domain == '' || $filename == '' )
  524.         {
  525.             $this->errMsg 'the value of parameter (domain,filename) can not be empty!';
  526.             $this->errNum = -101;
  527.             return false;
  528.         }
  529.  
  530.         try {
  531.             $container $this->swift_conn->get_container($domain);
  532.         catch (Exception $e{
  533.             $this->errMsg $e->getMessage();
  534.             $this->errNum = -122;
  535.             return false;
  536.         }
  537.  
  538.         $this->setUrl$this->getDom($domain)$filename );
  539.  
  540.         try {
  541.             $object $container->get_object($filename);
  542.             $object $this->std_class_object_to_array($object);
  543.             if !empty($object['last_modified']) ) {
  544.                 $file_attr array(
  545.                     'fileName'=>$object['name'],
  546.                     'datetime'=>strtotime($object['last_modified']),
  547.                     'content_type'=>$object['content_type'],
  548.                     'length'=>$object['content_length'],
  549.                     'md5sum'=>$object['etag'],
  550.                     'expires'=>array_key_exists('Expires'$object['metadata'])?$object['metadata']['Expires']:NULL
  551.                     );
  552.                 if (count($attrKey!= 0{
  553.                     $tmp_array array();
  554.                     foreach ($attrKey as $small{
  555.                         $tmp_array[$small$file_attr[$small];
  556.                     }
  557.                     $file_attr $tmp_array;
  558.                 }
  559.             else {
  560.                 $file_attr false;
  561.             }
  562.             return $file_attr;  
  563.         catch (Exception $e{
  564.             $this->errMsg $e->getMessage();
  565.             $this->errNum = -115;
  566.             return false;
  567.         }              
  568.     }
  569.  
  570.  
  571.     /**
  572.      * 检查文件是否存在
  573.      *
  574.      * @param string $domain    存储域
  575.      * @param string $filename  文件地址
  576.      * @return bool 
  577.      */
  578.     public function fileExists$domain$filename )
  579.     {
  580.         $domain $this->parseDomain(trim($domain));
  581.         $filename $this->formatFilename($filename);
  582.  
  583.         if $domain == '' || $filename == '' )
  584.         {
  585.             $this->errMsg 'the value of parameter (domain,filename) can not be empty!';
  586.             $this->errNum = -101;
  587.             return false;
  588.         }
  589.         $file_exist $this->getAttr($domain,$filename);
  590.         return ($file_exist === false)?false:true;
  591.     }
  592.  
  593.     /**
  594.      * 获取文件的内容
  595.      *
  596.      * @param string $domain 
  597.      * @param string $filename 
  598.      * @return string 成功时返回文件内容,否则返回false
  599.      */
  600.     public function read$domain$filename )
  601.     {
  602.         $domain $this->parseDomain(trim($domain));
  603.         $filename $this->formatFilename($filename);
  604.  
  605.         if $domain == '' || $filename == '' )
  606.         {
  607.             $this->errMsg 'the value of parameter (domain,filename) can not be empty!';
  608.             $this->errNum = -101;
  609.             return false;
  610.         }
  611.         $this->setUrl$this->getDom($domain)$filename );
  612.  
  613.         try {
  614.             $container $this->swift_conn->get_container($domain);
  615.         catch (Exception $e{
  616.             $this->errMsg $e->getMessage();
  617.             $this->errNum = -122;
  618.             return false;
  619.         }
  620.  
  621.         try {
  622.             $object $container->get_object($filename);
  623.         catch (Exception $e{
  624.             $this->errMsg $e->getMessage();
  625.             $this->errNum = -127;
  626.             return false;
  627.         }
  628.         
  629.         try {
  630.             $data $object->read();
  631.             return $data
  632.         catch (Exception $e{
  633.             $this->errMsg $e->getMessage();
  634.             $this->errNum = -116;
  635.             return false;
  636.         }
  637.                
  638.     }
  639.  
  640.     /**
  641.      * 删除文件
  642.      *
  643.      * @param string $domain 
  644.      * @param string $filename 
  645.      * @return bool 
  646.      */
  647.     public function delete$domain$filename )
  648.     {
  649.         $domain $this->parseDomain(trim($domain));
  650.         //$filename = $this->formatFilename($filename);
  651.  
  652.         if $domain == '' || $filename == '' )
  653.         {
  654.             $this->errMsg 'the value of parameter (domain,filename) can not be empty!';
  655.             $this->errNum = -101;
  656.             return false;
  657.         }
  658.         $this->setUrl$this->getDom($domain)$filename );
  659.  
  660.         try {
  661.             $container $this->swift_conn->get_container($domain);
  662.         catch (Exception $e{
  663.             $this->errMsg $e->getMessage();
  664.             $this->errNum = -122;
  665.             return false;
  666.         }
  667.  
  668.         try {
  669.             $result $container->delete_object($filename);
  670.             return $result;
  671.         catch (Exception $e{
  672.             $this->errMsg $e->getMessage();
  673.             $this->errNum = -117;
  674.             return false;
  675.         }
  676.                 
  677.     }
  678.  
  679.     /**
  680.      * 设置文件属性
  681.      *
  682.      * 目前支持的文件属性
  683.      *  - expires: 浏览器缓存超时,设置规则和domain expires的规则一致
  684.      *  - encoding: 设置通过Web直接访问文件时,Header中的Content-Encoding。
  685.      *  - type: 设置通过Web直接访问文件时,Header中的Content-Type。
  686.      *  - private: 设置文件为私有,则文件不可被下载。
  687.      *
  688.      * <code>
  689.      * <?php
  690.      * $stor = new SaeStorage();
  691.      * 
  692.      * $attr = array('expires' => '1 y');
  693.      * $ret = $stor->setFileAttr("test", "test.txt", $attr);
  694.      * if ($ret === false) {
  695.      *      var_dump($stor->errno(), $stor->errmsg());
  696.      * }
  697.      * ?>
  698.      * </code>
  699.      *
  700.      * @param string $domain 
  701.      * @param string $filename  文件名
  702.      * @param array $attr       文件属性。格式:array('attr0'=>'value0', 'attr1'=>'value1', ......);
  703.      * @return bool 
  704.      */
  705.     public function setFileAttr$domain$filename$attr array() )
  706.     {
  707.         $domain $this->parseDomain(trim($domain));
  708.         $filename $this->formatFilename($filename);
  709.  
  710.         if $domain == '' || $filename == '' {
  711.             $this->errMsg 'the value of parameter domain,filename can not be empty!';
  712.             $this->errNum = -101;
  713.             return false;
  714.         }
  715.  
  716.         $parseAttr $this->parseFileAttr($attr);
  717.         if ($parseAttr == false{
  718.             $this->errMsg 'the value of parameter attr must be an array, and can not be empty!';
  719.             $this->errNum = -101;
  720.             return false;
  721.         }
  722.         try {
  723.             $container $this->swift_conn->get_container($domain);
  724.         catch (Exception $e{
  725.             $this->errMsg $e->getMessage();
  726.             $this->errNum = -122;
  727.             return false;
  728.         }
  729.  
  730.         try {
  731.             $object $container->get_object($filename);
  732.         catch (Exception $e{
  733.             $this->errMsg $e->getMessage();
  734.             $this->errNum = -127;
  735.             return false;
  736.         }
  737.         
  738.         $object->metadata $attr;
  739.         try {
  740.             $result $object->sync_metadata();
  741.             return $result;
  742.         catch (Exception $e{
  743.             $this->errMsg $e->getMessage();
  744.             $this->errNum = -118;
  745.             return false;
  746.         }
  747.         
  748.     }
  749.  
  750.     /**
  751.      * 设置Domain属性
  752.      *
  753.      * 目前支持的Domain属性
  754.      *  - expires: 浏览器缓存超时
  755.      *  说明:
  756.      *  - expires 格式:[modified] TIME_DELTA,例如modified 1y或者1y,modified关键字用于指定expire时间相对于文件的修改时间。默认expire时间是相对于access time。如果TIME_DELTA为负, Cache-Control header会被设置为no-cache。
  757.      *  - TIME_DELTA,TIME_DELTA是一个表示时间的字符串,例如: 1y3M 48d 5s
  758.      *  - 目前支持s/m/h/d/w/M/y
  759.      *  - expires_type 格式:TYPE [modified] TIME_DELTA,TYPE为文件的mimetype,例如text/html, text/plain, image/gif。多条expires-type规则之间以 , 隔开。例如:text/html 48h,image/png modified 1y
  760.      *  - allowReferer: 根据Referer防盗链
  761.      *  - private: 是否私有Domain
  762.      *  - 404Redirect: 404跳转页面,只能是本应用页面,或本应用Storage中文件。例如http://appname.sinaapp.com/404.html或http://appname-domain.stor.sinaapp.com/404.png
  763.      *  - tag: Domain简介。格式:array('tag1', 'tag2')
  764.      * <code>
  765.      * <?php
  766.      * // 缓存过期设置
  767.      * $expires = '1 d
  768.      * ';
  769.      *
  770.      * // 防盗链设置
  771.      * $allowReferer = array();
  772.      * $allowReferer['hosts'][] = '*.elmerzhang.com';       // 允许访问的来源域名,千万不要带 http://。支持通配符*和?
  773.      * $allowReferer['hosts'][] = 'elmer.sinaapp.com';
  774.      * $allowReferer['hosts'][] = '?.elmer.sinaapp.com';
  775.      * $allowReferer['redirect'] = 'http://elmer.sinaapp.com/'; // 盗链时跳转到的地址,仅允许跳转到本APP的页面,且不可使用独立域名。如果不设置或者设置错误,则直接拒绝访问。
  776.      * //$allowReferer = false;  // 如果要关闭一个Domain的防盗链功能,直接将allowReferer设置为false即可
  777.      * 
  778.      * $stor = new SaeStorage();
  779.      * 
  780.      * $attr = array('expires'=>$expires, 'allowReferer'=>$allowReferer);
  781.      * $ret = $stor->setDomainAttr("test", $attr);
  782.      * if ($ret === false) {
  783.      *      var_dump($stor->errno(), $stor->errmsg());
  784.      * }
  785.      *
  786.      * ?>
  787.      * </code>
  788.      *
  789.      * @param string $domain 
  790.      * @param array $attr       Domain属性。格式:array('attr0'=>'value0', 'attr1'=>'value1', ......);
  791.      * @return bool 
  792.      */
  793.     public function setDomainAttr$domain$attr array() )
  794.     {
  795.         $domain $this->parseDomain(trim($domain));
  796.  
  797.         if $domain == '' )
  798.         {
  799.             $this->errMsg 'The value of parameter domain can not be empty!';
  800.             $this->errNum = -101;
  801.             return false;
  802.         }
  803.  
  804.         $parseAttr $this->parseDomainAttr($attr);
  805.  
  806.         if ($parseAttr == false{
  807.             $this->errMsg 'The value of parameter attr must be an array, and can not be empty!';
  808.             $this->errNum = -101;
  809.             return false;
  810.         }
  811.  
  812.         try {
  813.             $container $this->swift_conn->get_container($domain);
  814.         catch (Exception $e{
  815.             $this->errMsg $e->getMessage();
  816.             $this->errNum = -122;
  817.             return false;
  818.         }
  819.  
  820.         $container->metadata $attr;
  821.         try {
  822.             $result $container->sync_metadata();
  823.             return($result);
  824.         catch (Exception $e{
  825.             $this->errMsg $e->getMessage();
  826.             $this->errNum = -119;
  827.             return false;
  828.         }
  829.               
  830.     }
  831.  
  832.     /**
  833.      * 获取domain所占存储的大小
  834.      *
  835.      * @param string $domain 
  836.      * @return int 
  837.      */
  838.     public function getDomainCapacity$domain )
  839.     {
  840.         $domain $this->parseDomain(trim($domain));
  841.         if (empty($domain)) {
  842.             $this->errMsg 'The value of parameter \'$domain\' can not be empty!';
  843.             $this->errNum = -101;
  844.             return false;
  845.         }
  846.  
  847.         try {
  848.            $info $this->swift_conn->get_container($domain)
  849.         catch (Exception $e{
  850.             $this->errMsg $e->getMessage();
  851.             $this->errNum = -120;
  852.             return false;
  853.         }
  854.  
  855.         $info_array $this->std_class_object_to_array($info);
  856.         return $info_array['bytes_used'];
  857.     }
  858.  
  859.  
  860.     /**
  861.      * 创建一个domain
  862.      * 
  863.      * @desc
  864.      * 
  865.      * @access private
  866.      * @param $domain='' 
  867.      * @param $attr=array('private'=>false 
  868.      * @return void 
  869.      * @exception none
  870.      * @ignore
  871.      */
  872.     public function createDomain$domain=''$attr array('private'=>false) )
  873.     {
  874.         $domain strtolower($domain);
  875.         if strlen$domain 100 || strlen$domain {
  876.             return array'errno'=>-102'errmsg'=>'Domain length invalid(5,100)!domain('.$domain.')' );
  877.         }
  878.  
  879.         if Empty$domain ) ) {
  880.             $this->errMsg 'The value of parameter \'domain\' can not be empty!';
  881.             $this->errNum = -101;
  882.             return false;
  883.         }
  884.  
  885.         $domain_explode explode("-"$domain);
  886.         if (count($domain_explode!= 2{
  887.             $this->errMsg 'The value of parameter \'domain\' is not legit!';
  888.             $this->errNum = -101;
  889.             return false;
  890.         else {
  891.             $domain $domain_explode[1];
  892.         }
  893.  
  894.         try {
  895.             $this->swift_conn->create_container($domain);
  896.             try {
  897.                 if (count($attr)) {
  898.                     $this->setDomainAttr($domain,$attr);
  899.                 }
  900.                 return true;
  901.             catch (Exception $e{
  902.                 $this->errMsg sprintf("Set domain attr failed, %s"$e->getMessage());
  903.                 $this->errNum = -107;
  904.                 return false;
  905.             }
  906.         catch (Exception $e{
  907.             $this->errMsg sprintf("Create domain failed, %s"$e->getMessage());
  908.             $this->errNum = -104;
  909.             return false;           
  910.         }
  911.     }
  912.  
  913.  
  914.     /**
  915.      * 获取domain列表
  916.      * 
  917.      * @desc
  918.      * 
  919.      * @access public
  920.      * @return void 
  921.      * @exception none
  922.      */
  923.     public function listDomains()
  924.     {
  925.         try {
  926.             $ret $this->swift_conn->get_containers(0);
  927.             $ret $this->std_class_object_to_array($ret);
  928.             foreach ($ret as $small{
  929.                 $retnew[$this->appName.'-'.$small['name'];
  930.             }
  931.             return $retnew;
  932.         catch (Exception $e{
  933.             $this->errNum = -108;
  934.             $this->errMsg $e->getMessage();
  935.             return false;
  936.         }
  937.     }
  938.  
  939.  
  940.     /**
  941.      * 获取域名属性
  942.      * 
  943.      * @desc
  944.      * 
  945.      * @access public
  946.      * @param $domain='' 
  947.      * @return void 
  948.      * @exception none
  949.      */
  950.     public function getDomainAttr$domain='' )
  951.     {
  952.         $domain strtolower($domain);
  953.         if (empty($domain)) {
  954.             $this->errMsg 'The value of parameter \'domain\' can not be empty!';
  955.             $this->errNum = -101;
  956.             return false;
  957.         }
  958.  
  959.         $domain_explode explode("-"$domain);
  960.         if (count($domain_explode!= 2{
  961.             $this->errMsg 'The value of parameter \'domain\' is not legit!';
  962.             $this->errNum = -101;
  963.             return false;
  964.         else {
  965.             $domain $domain_explode[1];
  966.         }
  967.  
  968.         try {
  969.             $ret $this->swift_conn->get_container($domain);
  970.             $info_array $this->std_class_object_to_array($ret);
  971.             $retmsg array(
  972.                 'expires'=>$info_array['metadata']['X-Sws-Container-Meta-Expires'],
  973.                 'expires_type'=>$info_array['metadata']['X-Sws-Container-Meta-Expires-Type'],
  974.                 'fileNum'=>$info_array['object_count'],
  975.                 'tag'=>json_decode($info_array['metadata']['X-Sws-Container-Meta-Tags'],true),
  976.                 'dataSize'=>(int)$info_array['bytes_used'],
  977.                 );
  978.             if isset$info_array['read') ) {
  979.                 $rrules explode(','$info_array['read']);
  980.                 if in_array('.r:*'$rrules) ) {
  981.                     $retmsg['allowReferer'array();
  982.                     $retmsg['allowReferer']['hosts'array();
  983.                     foreach $rrules as $rrule {
  984.                         if substr($rrule03== '.r:' {
  985.                             $retmsg['allowReferer']['hosts'][substr($rrule3);
  986.                         elseif substr($rrule04== '.rd:' {
  987.                             $retmsg['allowReferer']['redirect'substr($rrule4);
  988.                         }
  989.                     }
  990.                     if !$retmsg['allowReferer']['hosts'{
  991.                         $retmsg['private'true;
  992.                     }
  993.                 else {
  994.                     $retmsg['private'false;
  995.                 }
  996.             else {
  997.                 $retmsg['private'true;
  998.             }
  999.             return $retmsg;
  1000.         catch (Exception $e{
  1001.             $this->errNum = -109;
  1002.             $this->errMsg $e->getMessage();
  1003.             return false;
  1004.         }
  1005.         
  1006.     }
  1007.  
  1008.  
  1009.     /**
  1010.      * 删除一个domain
  1011.      * 
  1012.      * @desc
  1013.      * 
  1014.      * @access public
  1015.      * @param $domain 
  1016.      * @param $force=0 
  1017.      * @return void 
  1018.      * @exception none
  1019.      * @ignore
  1020.      */
  1021.     public function deleteDomain$domain $force )
  1022.     {
  1023.         $domain strtolower($domain);
  1024.         if empty$domain ) ) {
  1025.             $this->errMsg 'The value of parameter \'domain\' can not be empty!';
  1026.             $this->errNum = -101;
  1027.             return false;
  1028.         }
  1029.  
  1030.         $domain_explode explode("-"$domain);
  1031.         if (count($domain_explode!= 2{
  1032.             $this->errMsg 'The value of parameter \'domain\' is not legit!';
  1033.             $this->errNum = -101;
  1034.             return false;
  1035.         else {
  1036.             $domain $domain_explode[1];
  1037.         }
  1038.  
  1039.         // 循环删除container的文件
  1040.         $files $this->getList($domain);
  1041.         while is_array($files&& count($files{
  1042.             foreach ($files as $file{
  1043.                 $this->delete($domain$file);
  1044.             }
  1045.             $files $this->getList($domain);
  1046.         }
  1047.  
  1048.         try {
  1049.             $this->swift_conn->delete_container($domain);
  1050.             return true;
  1051.         catch (Exception $e{
  1052.             $this->errNum = -105;
  1053.             $this->errMsg $e->getMessage();
  1054.             return false;
  1055.         }       
  1056.     }
  1057.  
  1058.     /**
  1059.      * @ignore
  1060.      */
  1061.     public function runFile$domain,  $filename)
  1062.     {
  1063.         $this->errMsg 'this function is discarded';
  1064.         $this->errNum = -221;
  1065.         return false;
  1066.     }
  1067.  
  1068.     /**
  1069.      * domain拼接
  1070.      * @param string $domain 
  1071.      * @param bool $concat 
  1072.      * @return string 
  1073.      * @author Elmer Zhang
  1074.      * @ignore
  1075.      */
  1076.     protected function getDom($domain$concat true{
  1077.         $domain strtolower(trim($domain));
  1078.  
  1079.         if ($concat{
  1080.             ifstrpos($domain'-'=== false {
  1081.                 $domain $this->appName .'-'$domain;
  1082.             }
  1083.         else {
  1084.             if ( ( $pos strpos($domain'-') ) !== false {
  1085.                 $domain substr($domain$pos 1);
  1086.             }
  1087.         }
  1088.         return $domain;
  1089.     }
  1090.  
  1091.  
  1092.     /**
  1093.      * Format Filename.
  1094.      *
  1095.      * @param string $filename 
  1096.      * @return string 
  1097.      * @ignore
  1098.      */
  1099.     private function formatFilename($filename
  1100.     {
  1101.         $filename trim($filename);
  1102.         $encodings array'UTF-8''GBK''BIG5' );
  1103.         $charset mb_detect_encoding$filename $encodings);
  1104.         if $charset !='UTF-8' {
  1105.             $filename mb_convert_encoding$filename"UTF-8"$charset);
  1106.         }
  1107.  
  1108.         $filename preg_replace('/\/\.\//''/'$filename);
  1109.         $filename ltrim($filename'/');
  1110.         $filename preg_replace('/^\.\//'''$filename);
  1111.         while preg_match('/\/\//'$filename) ) {
  1112.             $filename preg_replace('/\/\//''/'$filename);
  1113.         }
  1114.         return $filename;
  1115.     }
  1116.  
  1117.     /**
  1118.      * @ignore
  1119.      */
  1120.     protected function parseDomainAttr($attr
  1121.     {
  1122.         $parseAttr array();
  1123.  
  1124.         if !is_array$attr || empty$attr ) ) {
  1125.             return false;
  1126.         }
  1127.  
  1128.         foreach $attr as $k => $a {
  1129.             switch strtolower$k ) ) {
  1130.                 case '404redirect':
  1131.                     if !empty($a&& is_string($a) ) {
  1132.                         $parseAttr['404Redirect'trim($a);
  1133.                     }
  1134.                     break;
  1135.                 case 'private':
  1136.                     $parseAttr['private'$a true false;
  1137.                     break;
  1138.                 case 'expires':
  1139.                     $parseAttr['expires'$a;
  1140.                     break;
  1141.                 case 'expires_type':
  1142.                     $parseAttr['expires_type'$a;
  1143.                     break;
  1144.                 case 'allowreferer':
  1145.                     if isset($a['hosts']&& is_array($a['hosts']&& !empty($a['hosts']) ) {
  1146.                         $parseAttr['allowReferer'array();
  1147.                         $parseAttr['allowReferer']['hosts'$a['hosts'];
  1148.  
  1149.                         if isset($a['redirect']&& is_string($a['redirect']) ) {
  1150.                             $parseAttr['allowReferer']['redirect'$a['redirect'];
  1151.                         }
  1152.                     else {
  1153.                         $parseAttr['allowReferer']['host'false;
  1154.                     }
  1155.                     break;
  1156.                 case 'tag':
  1157.                     if (is_array($a&& !empty($a)) {
  1158.                         $parseAttr['tag'array();
  1159.                         foreach ($a as $v{
  1160.                             $v trim($v);
  1161.                             if (is_string($v&& !empty($v)) {
  1162.                                 $parseAttr['tag'][$v;
  1163.                             }
  1164.                         }
  1165.                     }
  1166.                     break;
  1167.                 default:
  1168.                     break;
  1169.             }
  1170.         }
  1171.  
  1172.         return $parseAttr;
  1173.     }
  1174.  
  1175.     /**
  1176.      * @ignore
  1177.      */
  1178.     protected function parseFileAttr($attr
  1179.     {
  1180.         $parseAttr array();
  1181.  
  1182.         if !is_array$attr || empty$attr ) ) {
  1183.             return false;
  1184.         }
  1185.  
  1186.         foreach $attr as $k => $a {
  1187.             switch strtolower$k ) ) {
  1188.                 case 'expires':
  1189.                     $parseAttr['expires'$a;
  1190.                     break;
  1191.                 case 'encoding':
  1192.                     $parseAttr['encoding'$a;
  1193.                     break;
  1194.                 case 'type':
  1195.                     $parseAttr['type'$a;
  1196.                     break;
  1197.                 case 'private':
  1198.                     $parseAttr['private'intval($a);
  1199.                     break;
  1200.                 default:
  1201.                     break;
  1202.             }
  1203.         }
  1204.  
  1205.         return $parseAttr;
  1206.     }
  1207.  
  1208.      /**
  1209.      * @ignore
  1210.      */
  1211.     public function parseDomain$domain 
  1212.     {
  1213.         $domain strtolower($domain);
  1214.         if (strstr($domain,'-')) {
  1215.             list($account$containerexplode('-'$domain);
  1216.             return $container;
  1217.         else {
  1218.             return $domain;
  1219.         }
  1220.     }
  1221.  
  1222.      /**
  1223.      * @ignore
  1224.      */
  1225.     protected function std_class_object_to_array($stdclassobject)
  1226.     {
  1227.         $_array is_object($stdclassobjectget_object_vars($stdclassobject$stdclassobject;
  1228.         $array array();
  1229.         foreach ($_array as $key => $value{
  1230.             $value (is_array($value|| is_object($value)) $this->std_class_object_to_array($value$value;
  1231.             $array[$key$value;
  1232.         }
  1233.  
  1234.         return $array;
  1235.     }
  1236. }

Documentation generated on Wed, 03 Sep 2014 10:14:57 +0800 by phpDocumentor 1.4.3