BVB Source Codes

Ali cloud storage v1.1 PHP file upload system root directory Show sdk.class.php Source code

Return Download Ali cloud storage v1.1 PHP file upload system root directory: download sdk.class.php Source code - Download Ali cloud storage v1.1 PHP file upload system root directory Source code - Type:.php
  1. <?php
  2. //设置默认时区
  3. date_default_timezone_set('Asia/Shanghai');
  4. //检测API路径
  5. if(!defined('OSS_API_PATH'))
  6. define('OSS_API_PATH', dirname(__FILE__));
  7. require_once './conf.inc.php';
  8.  
  9. //加载conf.inc.php文件
  10. require_once './conf.inc.php';
  11.  
  12. //加载RequestCore
  13. require_once OSS_API_PATH.DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR.'requestcore'.DIRECTORY_SEPARATOR.'requestcore.class.php';
  14.  
  15. //加载MimeTypes
  16. require_once OSS_API_PATH.DIRECTORY_SEPARATOR.'util'.DIRECTORY_SEPARATOR.'mimetypes.class.php';
  17.  
  18. try{
  19.         if(file_exists(OSS_API_PATH.DIRECTORY_SEPARATOR.'lang'.DIRECTORY_SEPARATOR.LANG.'.inc.php')){
  20.                 require_once OSS_API_PATH.DIRECTORY_SEPARATOR.'lang'.DIRECTORY_SEPARATOR.LANG.'.inc.php';
  21.         }else{
  22.                 throw new OSS_Exception(OSS_LANG_FILE_NOT_EXIST);
  23.         }
  24. }catch (OSS_Exception $e){
  25.         die($e->getMessage());
  26. }
  27.  
  28. //定义软件名称,版本号等信息
  29. define('OSS_NAME','oss-sdk-php');
  30. define('OSS_VERSION','1.0.3');
  31. define('OSS_BUILD','201206121147');
  32. define('OSS_AUTHOR', 'xxx@xxx.com');
  33.  
  34. // EXCEPTIONS
  35.  
  36. /**
  37.  * OSS异常类,继承自基类
  38.  */
  39. class OSS_Exception extends Exception {}
  40.  
  41.  
  42. //检测CURL扩展
  43. $extensions = get_loaded_extensions();
  44. if($extensions){
  45.         if(!in_array('curl', $extensions)){
  46.                 throw new OSS_Exception(OSS_CURL_EXTENSION_MUST_BE_LOAD);
  47.         }
  48. }else{
  49.         throw new OSS_Exception(OSS_NO_ANY_EXTENSIONS_LOADED);
  50. }
  51.  
  52. //CLASS
  53. /**
  54.  * OSS基础类
  55.  * @author xiaobing.meng@alibaba-inc.com
  56.  * @since 2012-05-31
  57.  */
  58. class ALIOSS{
  59.         /*%******************************************************************************************%*/
  60.         // CONSTANTS
  61.  
  62.         /**
  63.          * OSS服务地址
  64.          */
  65.         const DEFAULT_OSS_HOST = 'storage.aliyun.com';
  66.  
  67.         /**
  68.          * 软件名称
  69.          */
  70.         const NAME = OSS_NAME;
  71.  
  72.         /**
  73.          * OSS软件Build ID
  74.          */
  75.         const BUILD = OSS_BUILD;
  76.  
  77.         /**
  78.          * 版本号
  79.          */
  80.         const VERSION = OSS_VERSION;
  81.  
  82.         /**
  83.          * 作者
  84.          */
  85.         const AUTHOR = OSS_AUTHOR;
  86.  
  87.         /*%******************************************************************************************%*/
  88.         //OSS 内部常量
  89.  
  90.         const OSS_BUCKET = 'bucket';
  91.         const OSS_OBJECT = 'object';
  92.         const OSS_HEADERS = 'headers';
  93.         const OSS_METHOD = 'method';
  94.         const OSS_QUERY = 'query';
  95.         const OSS_BASENAME = 'basename';
  96.         const OSS_MAX_KEYS = 'max-keys';
  97.         const OSS_UPLOAD_ID = 'uploadId';
  98.         const OSS_MAX_KEYS_VALUE = 100;
  99.         const OSS_MAX_OBJECT_GROUP_VALUE = 1000;
  100.         const OSS_FILE_SLICE_SIZE = 8192;
  101.         const OSS_PREFIX = 'prefix';
  102.         const OSS_DELIMITER = 'delimiter';
  103.         const OSS_MARKER = 'marker';
  104.         const OSS_CONTENT_MD5 = 'Content-Md5';
  105.         const OSS_CONTENT_TYPE = 'Content-Type';
  106.         const OSS_CONTENT_LENGTH = 'Content-Length';
  107.         const OSS_IF_MODIFIED_SINCE = 'If-Modified-Since';
  108.         const OSS_IF_UNMODIFIED_SINCE = 'If-Unmodified-Since';
  109.         const OSS_IF_MATCH = 'If-Match';
  110.         const OSS_IF_NONE_MATCH = 'If-None-Match';
  111.         const OSS_CACHE_CONTROL = 'Cache-Control';
  112.         const OSS_EXPIRES = 'Expires';
  113.         const OSS_CONTENT_COING = 'Content-Coding';
  114.         const OSS_CONTENT_DISPOSTION = 'Content-Disposition';
  115.         const OSS_RANGE = 'Range';
  116.         const OS_CONTENT_RANGE = 'Content-Range';
  117.         const OSS_CONTENT = 'content';
  118.         const OSS_BODY = 'body';
  119.         const OSS_LENGTH = 'length';
  120.         const OSS_HOST = 'Host';
  121.         const OSS_DATE = 'Date';
  122.         const OSS_AUTHORIZATION = 'Authorization';
  123.         const OSS_FILE_DOWNLOAD = 'fileDownload';
  124.         const OSS_FILE_UPLOAD = 'fileUpload';
  125.         const OSS_PART_SIZE = 'partSize';
  126.         const OSS_SEEK_TO = 'seekTo';
  127.         const OSS_SIZE = 'size';
  128.         const OSS_QUERY_STRING = 'query_string';
  129.         const OSS_SUB_RESOURCE = 'sub_resource';
  130.         const OSS_DEFAULT_PREFIX = 'x-oss-';
  131.  
  132.         /*%******************************************************************************************%*/
  133.         //私有URL变量
  134.  
  135.         const OSS_URL_ACCESS_KEY_ID = 'OSSAccessKeyId';
  136.         const OSS_URL_EXPIRES = 'Expires';
  137.         const OSS_URL_SIGNATURE = 'Signature';
  138.  
  139.         /*%******************************************************************************************%*/
  140.         //HTTP方法
  141.  
  142.         const OSS_HTTP_GET = 'GET';
  143.         const OSS_HTTP_PUT = 'PUT';
  144.         const OSS_HTTP_HEAD = 'HEAD';
  145.         const OSS_HTTP_POST = 'POST';
  146.         const OSS_HTTP_DELETE = 'DELETE';
  147.  
  148.  
  149.         /*%******************************************************************************************%*/
  150.         //其他常量
  151.  
  152.         //x-oss
  153.         const OSS_ACL = 'x-oss-acl';
  154.  
  155.         //OBJECT GROUP
  156.         const OSS_OBJECT_GROUP = 'x-oss-file-group';
  157.        
  158.         //Multi Part
  159.         const OSS_MULTI_PART = 'uploads';
  160.        
  161.         //Multi Delete
  162.         const OSS_MULTI_DELETE = 'delete';
  163.  
  164.         //OBJECT COPY SOURCE
  165.         const OSS_OBJECT_COPY_SOURCE = 'x-oss-copy-source';
  166.  
  167.         //private,only owner
  168.         const OSS_ACL_TYPE_PRIVATE = 'private';
  169.  
  170.         //public reand
  171.         const OSS_ACL_TYPE_PUBLIC_READ = 'public-read';
  172.  
  173.         //public read write
  174.         const OSS_ACL_TYPE_PUBLIC_READ_WRITE = 'public-read-write';
  175.  
  176.         //OSS ACL数组
  177.         static $OSS_ACL_TYPES = array(
  178.         self::OSS_ACL_TYPE_PRIVATE,
  179.         self::OSS_ACL_TYPE_PUBLIC_READ,
  180.         self::OSS_ACL_TYPE_PUBLIC_READ_WRITE
  181.         );
  182.  
  183.  
  184.         /*%******************************************************************************************%*/
  185.         // PROPERTIES
  186.  
  187.         /**
  188.          * 是否使用SSL
  189.          */
  190.         protected $use_ssl = false;
  191.  
  192.         /**
  193.          * 是否开启debug模式
  194.          */
  195.         private $debug_mode = true;
  196.        
  197.         /**
  198.          * 最大重试次数
  199.          */
  200.         private $max_retries = 3;
  201.        
  202.         /**
  203.          * 已经重试次数
  204.          */
  205.         private   $redirects = 0;      
  206.        
  207.         /**
  208.          * 虚拟地址
  209.          */
  210.         private $vhost;
  211.        
  212.         /**
  213.          * 路径表现方式
  214.          */
  215.         private $enable_domain_style = false;
  216.        
  217.         /**
  218.          * 请求URL
  219.          */
  220.         private  $request_url;
  221.        
  222.         /**
  223.          * OSS API ACCESS ID
  224.          */
  225.         private $access_id;
  226.  
  227.         /**
  228.          * OSS API ACCESS KEY
  229.          */
  230.         private $access_key;
  231.  
  232.         /**
  233.          * hostname
  234.          */
  235.         private $hostname;
  236.        
  237.         /**
  238.          * port number
  239.          */
  240.         private $port;
  241.  
  242.         /*%******************************************************************************************************%*/
  243.         //Constructor
  244.  
  245.         /**
  246.          * 默认构造函数
  247.          * @param string $_access_id (Optional)
  248.          * @param string $access_key (Optional)
  249.          * @param string $hostname (Optional)
  250.          * @throws OSS_Exception
  251.          * @author      xiaobing.meng@alibaba-inc.com
  252.          * @since       2011-11-08
  253.          */
  254.         public function __construct($access_id = NULL,$access_key = NULL, $hostname = NULL  ){
  255.                 //验证access_id,access_key
  256.                 if(!$access_id && !defined('OSS_ACCESS_ID')){
  257.                                 throw new OSS_Exception(NOT_SET_OSS_ACCESS_ID);
  258.                 }
  259.  
  260.                 if(!$access_key && !defined('OSS_ACCESS_KEY')){
  261.                         throw new OSS_Exception(NOT_SET_OSS_ACCESS_KEY);
  262.                 }
  263.  
  264.                 if($access_id && $access_key){
  265.                         $this->access_id = $access_id;
  266.                         $this->access_key = $access_key;
  267.                 }elseif (defined('OSS_ACCESS_ID') && defined('OSS_ACCESS_KEY')){
  268.                         $this->access_id = OSS_ACCESS_ID;
  269.                         $this->access_key = OSS_ACCESS_KEY;
  270.                 }else{
  271.                         throw new OSS_Exception(NOT_SET_OSS_ACCESS_ID_AND_ACCESS_KEY);
  272.                 }
  273.  
  274.                 //校验access_id&access_key
  275.                 if(empty($this->access_id) || empty($this->access_key)){
  276.                         throw new OSS_Exception(OSS_ACCESS_ID_OR_ACCESS_KEY_EMPTY);
  277.                 }
  278.  
  279.                 //校验hostname
  280.                 if(NULL === $hostname){
  281.                         $this->hostname = self::DEFAULT_OSS_HOST;
  282.                 }else{
  283.                         $this->hostname = $hostname;
  284.                 }
  285.         }
  286.  
  287.  
  288.         /*%******************************************************************************************************%*/
  289.         //属性
  290.        
  291.         /**
  292.          * 设置debug模式
  293.          * @param boolean $debug_mode (Optional)
  294.          * @author xiaobing.meng@alibaba-inc.com
  295.          * @since 2012-05-29
  296.          * @return void
  297.          */
  298.         public function set_debug_mode($debug_mode = true){
  299.                 $this->debug_mode = $debug_mode;
  300.         }
  301.        
  302.         /**
  303.          * 设置最大尝试次数
  304.          * @param int $max_retries
  305.          * @author xiaobing.meng@alibaba-inc.com
  306.          * @since 2012-05-29
  307.          * @return void
  308.          */
  309.         public function set_max_retries($max_retries = 3){
  310.                 $this->max_retries = $max_retries;
  311.         }
  312.        
  313.         /**
  314.          * 获取最大尝试次数
  315.          * @author xiaobing.meng@alibaba-inc.com
  316.          * @since 2012-05-29
  317.          * @return int
  318.          */
  319.         public function get_max_retries(){
  320.                 return $this->max_retries;
  321.         }
  322.  
  323.         /**
  324.          * 设置host地址
  325.          * @author xiaobing.meng@alibaba-inc.com
  326.          * @param string $hostname host name
  327.          * @param int   $port int
  328.          * @since 2012-06-11
  329.          * @return void
  330.          */
  331.         public function set_host_name($hostname,$port = null){
  332.                 $this->hostname = $hostname;
  333.                
  334.                 if($port){
  335.                         $this->port = $port;
  336.                         $this->hostname .= ':'.$port;
  337.                 }
  338.         }
  339.        
  340.         /**
  341.          * 设置vhost地址
  342.          * @author xiaobing.meng@alibaba-inc.com
  343.          * @param string $vhost vhost
  344.          * @since 2012-06-11
  345.          * @return void
  346.          */
  347.         public function set_vhost($vhost){
  348.                 $this->vhost = $vhost;
  349.         }
  350.        
  351.         /**
  352.          * 设置路径形式,如果为true,则启用三级域名,如bucket.storage.aliyun.com
  353.          * @author xiaobing.meng@alibaba-inc.com
  354.          * @param boolean $enable_domain_style
  355.          * @since 2012-06-11
  356.          * @return void
  357.          */
  358.         public function set_enable_domain_style($enable_domain_style = true){
  359.                 $this->enable_domain_style = $enable_domain_style;
  360.         }
  361.  
  362.        
  363.         /*%******************************************************************************************************%*/
  364.         //请求
  365.  
  366.         /**
  367.          * Authorization
  368.          * @param array $options (Required)
  369.          * @throws OSS_Exception
  370.          * @author xiaobing.meng@alibaba-inc.com
  371.          * @since 2012-05-31
  372.          */
  373.         public function auth($options){
  374.                 //开始记录LOG
  375.                 $msg = "---LOG START---------------------------------------------------------------------------\n";
  376.                
  377.                 //验证Bucket,list_bucket时不需要验证
  378.                 if(!( ('/' == $options[self::OSS_OBJECT]) && ('' == $options[self::OSS_BUCKET]) && ('GET' == $options[self::OSS_METHOD])) && !$this->validate_bucket($options[self::OSS_BUCKET])){
  379.                         throw new OSS_Exception('"'.$options[self::OSS_BUCKET].'"'.OSS_BUCKET_NAME_INVALID);
  380.                 }
  381.        
  382.                 //验证Object
  383.                 if(isset($options[self::OSS_OBJECT]) && !$this->validate_object($options[self::OSS_OBJECT])){
  384.                         throw  new OSS_Exception($options[self::OSS_OBJECT].OSS_OBJECT_NAME_INVALID);
  385.                 }
  386.                
  387.                 //Object编码为UTF-8
  388.                 if($this->is_gb2312($options[self::OSS_OBJECT])){
  389.                         $options[self::OSS_OBJECT] = iconv('GB2312', "UTF-8",$options[self::OSS_OBJECT]);
  390.                 }elseif($this->check_char($options[self::OSS_OBJECT],true)){
  391.                         $options[self::OSS_OBJECT] = iconv('GBK', "UTF-8",$options[self::OSS_OBJECT]);
  392.                 }      
  393.  
  394.                
  395.                 //验证ACL
  396.                 if(isset($options[self::OSS_HEADERS][self::OSS_ACL]) && !empty($options[self::OSS_HEADERS][self::OSS_ACL])){
  397.                         if(!in_array(strtolower($options[self::OSS_HEADERS][self::OSS_ACL]), self::$OSS_ACL_TYPES)){
  398.                                 throw new OSS_Exception($options[self::OSS_HEADERS][self::OSS_ACL].':'.OSS_ACL_INVALID);
  399.                         }
  400.                 }
  401.  
  402.                                
  403.                 //定义scheme
  404.                 $scheme = $this->use_ssl ? 'https://' : 'http://';
  405.                
  406.                 if($this->enable_domain_style){
  407.                         $hostname = $this->vhost ? $this->vhost : (($options[self::OSS_BUCKET] =='')?$this->hostname:($options[self::OSS_BUCKET].'.').$this->hostname);
  408.                 }else{
  409.                         $hostname = (isset($options[self::OSS_BUCKET]) && ''!==$options[self::OSS_BUCKET])?$this->hostname.'/'.$options[self::OSS_BUCKET]:$this->hostname;
  410.                 }
  411.  
  412.                
  413.                 //请求参数
  414.                 $resource = '';
  415.                 $sub_resource = '';
  416.                 $signable_resource = '';
  417.                 $query_string_params = array();
  418.                 $signable_query_string_params = array();
  419.                 $string_to_sign = '';          
  420.                
  421.                 $headers = array (
  422.                         self::OSS_CONTENT_MD5 => '',
  423.                         self::OSS_CONTENT_TYPE => isset($options[self::OSS_CONTENT_TYPE])?$options[self::OSS_CONTENT_TYPE]:'application/x-www-form-urlencoded',
  424.                         self::OSS_DATE => isset($options[self::OSS_DATE])? $options[self::OSS_DATE]: gmdate('D, d M Y H:i:s \G\M\T'),
  425.                         self::OSS_HOST => $this->enable_domain_style?$hostname:$this->hostname,
  426.                 );
  427.  
  428.                 if(isset ( $options [self::OSS_OBJECT] ) && '/' !== $options [self::OSS_OBJECT]){
  429.                         $signable_resource = '/'.str_replace('%2F', '/', rawurlencode($options[self::OSS_OBJECT]));
  430.                 }
  431.  
  432.                 if(isset($options[self::OSS_QUERY_STRING])){
  433.                         $query_string_params = array_merge($query_string_params,$options[self::OSS_QUERY_STRING]);
  434.                 }
  435.                 $query_string = $this->to_query_string($query_string_params);
  436.        
  437.                 $signable_list = array(
  438.                         'partNumber',
  439.                         'uploadId',                    
  440.                 );
  441.                
  442.                 foreach ($signable_list as $item){
  443.                         if(isset($options[$item])){
  444.                                 $signable_query_string_params[$item] = $options[$item];
  445.                         }
  446.                 }
  447.                 $signable_query_string = $this->to_query_string($signable_query_string_params);
  448.                
  449.                 //合并 HTTP headers
  450.                 if (isset ( $options [self::OSS_HEADERS] )) {
  451.                         $headers = array_merge ( $headers, $options [self::OSS_HEADERS] );
  452.                 }
  453.                
  454.                 //生成请求URL
  455.                 $conjunction = '?';
  456.                
  457.                 $non_signable_resource = '';
  458.  
  459.                 if (isset($options[self::OSS_SUB_RESOURCE])){
  460.                         $signable_resource .= $conjunction . $options[self::OSS_SUB_RESOURCE];
  461.                         $conjunction = '&';
  462.                 }      
  463.  
  464.                 if($signable_query_string !== ''){
  465.                         $signable_query_string = $conjunction.$signable_query_string;
  466.                         $conjunction = '&';
  467.                 }
  468.                
  469.                 if($query_string !== ''){
  470.                         $non_signable_resource .= $conjunction . $query_string;
  471.                         $conjunction = '&';                    
  472.                 }
  473.                
  474.                 $this->request_url =     $scheme . $hostname . $signable_resource . $signable_query_string . $non_signable_resource;
  475.  
  476.                 $msg .= "--REQUEST URL:----------------------------------------------\n".$this->request_url."\n";
  477.                
  478.                 //创建请求
  479.                 $request = new RequestCore($this->request_url);
  480.                  
  481.                 // Streaming uploads
  482.                 if (isset($options[self::OSS_FILE_UPLOAD])){
  483.                         if (is_resource($options[self::OSS_FILE_UPLOAD])){
  484.                                 $length = null;
  485.  
  486.                                 if (isset($options[self::OSS_CONTENT_LENGTH])){
  487.                                         $length = $options[self::OSS_CONTENT_LENGTH];
  488.                                 }elseif (isset($options[self::OSS_SEEK_TO])){
  489.                                        
  490.                                         $stats = fstat($options[self::OSS_FILE_UPLOAD]);
  491.  
  492.                                         if ($stats && $stats[self::OSS_SIZE] >= 0){
  493.                                                 $length = $stats[self::OSS_SIZE] - (integer) $options[self::OSS_SEEK_TO];
  494.                                         }
  495.                                 }
  496.  
  497.                                 $request->set_read_stream($options[self::OSS_FILE_UPLOAD], $length);
  498.  
  499.                                 if ($options[self::OSS_CONTENT_TYPE] === 'application/x-www-form-urlencoded'){
  500.                                         $options[self::OSS_CONTENT_TYPE] = 'application/octet-stream';
  501.                                 }
  502.                         }else{
  503.                                 $request->set_read_file($options[self::OSS_FILE_UPLOAD]);
  504.  
  505.                                 $length = $request->read_stream_size;
  506.  
  507.                                 if (isset($options[self::OSS_CONTENT_LENGTH])){
  508.                                         $length = $options[self::OSS_CONTENT_LENGTH];
  509.                                 }elseif (isset($options[self::OSS_SEEK_TO]) && isset($length)){
  510.                                         $length -= (integer) $options[self::OSS_SEEK_TO];
  511.                                 }
  512.  
  513.                                 $request->set_read_stream_size($length);
  514.  
  515.                                 if (isset($options[self::OSS_CONTENT_TYPE]) && ($options[self::OSS_CONTENT_TYPE] === 'application/x-www-form-urlencoded')){
  516.                                         $extension = explode('.', $options[self::OSS_FILE_UPLOAD]);
  517.                                         $extension = array_pop($extension);
  518.                                         $mime_type = OSSMimeTypes::get_mimetype($extension);
  519.                                         $options[self::OSS_CONTENT_TYPE] = $mime_type;
  520.                                 }
  521.                         }
  522.  
  523.                         $options[self::OSS_CONTENT_MD5] = '';
  524.                 }
  525.  
  526.                 if (isset($options[self::OSS_SEEK_TO])){
  527.                         $request->set_seek_position((integer) $options[self::OSS_SEEK_TO]);
  528.                 }      
  529.  
  530.                 if (isset($options[self::OSS_FILE_DOWNLOAD])){
  531.                         if (is_resource($options[self::OSS_FILE_DOWNLOAD])){
  532.                                 $request->set_write_stream($options[self::OSS_FILE_DOWNLOAD]);
  533.                         }else{
  534.                                 $request->set_write_file($options[self::OSS_FILE_DOWNLOAD]);
  535.                         }
  536.                 }              
  537.                
  538.                
  539.                 if(isset($options[self::OSS_METHOD])){
  540.                         $request->set_method($options[self::OSS_METHOD]);
  541.                         $string_to_sign .= $options[self::OSS_METHOD] . "\n";                  
  542.                 }
  543.                
  544.                 if (isset ( $options [self::OSS_CONTENT] )) {
  545.                         $request->set_body ( $options [self::OSS_CONTENT] );
  546.                        
  547.                         $headers[self::OSS_CONTENT_LENGTH] = strlen($options [self::OSS_CONTENT]);
  548.                         $headers[self::OSS_CONTENT_MD5] = $this->hex_to_base64(md5($options[self::OSS_CONTENT]));
  549.                 }
  550.  
  551.                 uksort($headers, 'strnatcasecmp');
  552.                
  553.                 foreach ( $headers as $header_key => $header_value ) {
  554.                         $header_value = str_replace ( array ("\r", "\n" ), '', $header_value );
  555.                         if ($header_value !== '') {
  556.                                 $request->add_header ( $header_key, $header_value );
  557.                         }
  558.  
  559.                         if (
  560.                                 strtolower($header_key) === 'content-md5' ||
  561.                                 strtolower($header_key) === 'content-type' ||
  562.                                 strtolower($header_key) === 'date' ||
  563.                                 (isset($options['self::OSS_EXPIRES']) && (integer) $options['self::OSS_EXPIRES'] > 0)
  564.                         ){
  565.                                 $string_to_sign .= $header_value . "\n";
  566.                         }elseif (substr(strtolower($header_key), 0, 6) === self::OSS_DEFAULT_PREFIX){
  567.                                 $string_to_sign .= strtolower($header_key) . ':' . $header_value . "\n";
  568.                         }                      
  569.                 }
  570.        
  571.                 $string_to_sign .= '/' . $options[self::OSS_BUCKET];
  572.                 $string_to_sign .=  $this->enable_domain_style ? ($options[self::OSS_BUCKET]!=''? ($options[self::OSS_OBJECT]=='/'?'/':'') :'' ) : '';
  573.                 $string_to_sign .= rawurldecode($signable_resource) . urldecode($signable_query_string);
  574.  
  575.                 $msg .= "STRING TO SIGN:----------------------------------------------\n".$string_to_sign."\n";
  576.                
  577.                 $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->access_key, true));
  578.                 $request->add_header('Authorization', 'OSS ' . $this->access_id . ':' . $signature);
  579.  
  580.                 if (isset($options[self::OSS_EXPIRES]) && (integer) $options[self::OSS_EXPIRES] > 0){
  581.                         return $this->request_url . $conjunction . self::OSS_URL_ACCESS_KEY_ID.'=' . $this->access_id . '&'.self::OSS_URL_EXPIRES.'=' . $options[self::OSS_EXPIRES] . '&'.self::OSS_URL_SIGNATURE.'=' . rawurlencode($signature);
  582.                 }elseif (isset($options[self::OSS_EXPIRES])){
  583.                         return $this->request_url;
  584.                 }              
  585.                
  586.                 if ($this->debug_mode){
  587.                         $request->debug_mode = $this->debug_mode;
  588.                 }
  589.  
  590.                 $msg .= "REQUEST HEADERS:----------------------------------------------\n".serialize($request->request_headers)."\n";
  591.                
  592.                 $request->send_request();
  593.  
  594.                 $response_header = $request->get_response_header();
  595.                 $response_header['x-oss-request-url'] = $this->request_url;
  596.                 $response_header['x-oss-redirects'] = $this->redirects;
  597.                 $response_header['x-oss-stringtosign'] = $string_to_sign;
  598.                 $response_header['x-oss-requestheaders'] = $request->request_headers;                          
  599.                
  600.                 $msg .= "RESPONSE HEADERS:----------------------------------------------\n".serialize($response_header)."\n";
  601.                
  602.                 $data =  new ResponseCore ( $response_header , $request->get_response_body (), $request->get_response_code () );
  603.                
  604.                 if((integer)$request->get_response_code() === 400 /*Bad Request*/ || (integer)$request->get_response_code() === 500 /*Internal Error*/ || (integer)$request->get_response_code() === 503 /*Service Unavailable*/){     
  605.                    if($this->redirects <= $this->max_retries ){
  606.                                 //设置休眠
  607.                                 $delay = (integer) (pow(4, $this->redirects) * 100000);
  608.                                 usleep($delay);
  609.                                 $this->redirects++;
  610.                                 $data = $this->auth($options);
  611.                    }
  612.                 }
  613.                
  614.                 $msg .= "RESPONSE DATA:----------------------------------------------\n".serialize($data)."\n";
  615.                 $msg .= date('Y-m-d H:i:s').":---LOG END---------------------------------------------------------------------------\n";
  616.                 //add log
  617.                 $this->log($msg);
  618.                
  619.                 $this->redirects = 0;  
  620.                 return $data;
  621.         }
  622.  
  623.  
  624.         /*%******************************************************************************************************%*/
  625.         //Service Operation
  626.  
  627.         /**
  628.          * Get Buket list
  629.          * @param array $options (Optional)
  630.          * @throws OSS_Exception
  631.          * @author xiaobing.meng@alibaba-inc.com
  632.          * @since 2011-11-14
  633.          * @return ResponseCore
  634.          */
  635.         public function list_bucket($options = NULL) {
  636.                 //$options
  637.                 $this->validate_options($options);
  638.  
  639.                 if (! $options) {
  640.                         $options = array ();
  641.                 }
  642.  
  643.                 $options[self::OSS_BUCKET] = '';
  644.                 $options[self::OSS_METHOD] = 'GET';
  645.                 $options[self::OSS_OBJECT] = '/';
  646.                 $response = $this->auth ( $options );
  647.  
  648.                 return $response;
  649.         }
  650.  
  651.  
  652.         /*%******************************************************************************************************%*/
  653.         //Bucket Operation
  654.  
  655.         /**
  656.          * Create Bucket
  657.          * @param string $bucket (Required)
  658.          * @param string $acl (Optional)
  659.          * @param array $options (Optional)
  660.          * @author xiaobing.meng@alibaba-inc.com
  661.          * @since 2011-11-14
  662.          * @return ResponseCore
  663.          */
  664.         public function create_bucket($bucket,$acl = self::OSS_ACL_TYPE_PRIVATE, $options = NULL){
  665.                 //$options
  666.                 $this->validate_options($options);
  667.  
  668.                 if (! $options) {
  669.                         $options = array ();
  670.                 }
  671.  
  672.                 //bucket
  673.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  674.  
  675.                 $options[self::OSS_BUCKET] = $bucket;
  676.                 $options[self::OSS_METHOD] = 'PUT';
  677.                 $options[self::OSS_OBJECT] = '/';
  678.                 $options[self::OSS_HEADERS] = array(self::OSS_ACL => $acl);
  679.                 $response = $this->auth ( $options );
  680.  
  681.                 return $response;
  682.         }
  683.  
  684.         /**
  685.          * Delete Bucket
  686.          * @param string $bucket (Required)
  687.          * @param array $options (Optional)
  688.          * @author xiaobing.meng@alibaba-inc.com
  689.          * @since 2011-11-14
  690.          * @return ResponseCore
  691.          */
  692.         public function delete_bucket($bucket,$options = NULL){
  693.                 //$options
  694.                 $this->validate_options($options);
  695.  
  696.                 if (! $options) {
  697.                         $options = array ();
  698.                 }
  699.  
  700.                 //bucket
  701.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  702.  
  703.                 $options[self::OSS_BUCKET] = $bucket;
  704.                 $options[self::OSS_METHOD] = 'DELETE';
  705.                 $options[self::OSS_OBJECT] = '/';
  706.                 $response = $this->auth ( $options );
  707.  
  708.                 return $response;
  709.         }
  710.  
  711.         /**
  712.          * Get Bucket's ACL
  713.          * @param string $bucket (Required)
  714.          * @param array $options (Optional)
  715.          * @throws OSS_Exception
  716.          * @author xiaobing.meng@alibaba-inc.com
  717.          * @since 2011-11-14
  718.          * @return ResponseCore
  719.          */
  720.         public function get_bucket_acl($bucket ,$options = NULL){
  721.                 //options
  722.                 $this->validate_options($options);
  723.  
  724.                 if(!$options){
  725.                         $options = array();
  726.                 }
  727.  
  728.                 //bucket
  729.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  730.  
  731.                 $options[self::OSS_BUCKET] = $bucket;
  732.                 $options[self::OSS_METHOD] = 'GET';
  733.                 $options[self::OSS_OBJECT] = '/';
  734.                 $options[self::OSS_SUB_RESOURCE] = 'acl';
  735.                 $response = $this->auth ( $options );
  736.  
  737.                 return $response;
  738.         }
  739.  
  740.         /**
  741.          * Set bucket'ACL
  742.          * @param string $bucket (Required)
  743.          * @param string $acl  (Required)
  744.          * @param array $options (Optional)
  745.          * @throws OSS_Exception
  746.          * @author xiaobing.meng@alibaba-inc.com
  747.          * @since 2011-11-14
  748.          * @return ResponseCore
  749.          */
  750.         public function set_bucket_acl($bucket ,$acl , $options = NULL){
  751.                 //options
  752.                 $this->validate_options($options);
  753.  
  754.                 if(!$options){
  755.                         $options = array();
  756.                 }
  757.  
  758.                 //bucket
  759.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  760.  
  761.                 $options[self::OSS_BUCKET] = $bucket;
  762.                 $options[self::OSS_METHOD] = 'PUT';
  763.                 $options[self::OSS_OBJECT] = '/';
  764.                 $options[self::OSS_HEADERS] = array(self::OSS_ACL => $acl);
  765.                 $response = $this->auth ( $options );
  766.  
  767.                 return $response;
  768.         }
  769.  
  770.  
  771.         /*%******************************************************************************************************%*/
  772.         //Object Operation
  773.  
  774.         /**
  775.          * List Object
  776.          * @param string $bucket (Required)
  777.          * @param array $options (Optional)
  778.          * 其中options中的参数如下
  779.          * $options = array(
  780.          *              'max-keys'      => max-keys用于限定此次返回object的最大数,如果不设定,默认为100,max-keys取值不能大于100。
  781.          *              'prefix'        => 限定返回的object key必须以prefix作为前缀。注意使用prefix查询时,返回的key中仍会包含prefix。
  782.          *              'delimiter' => 是一个用于对Object名字进行分组的字符。所有名字包含指定的前缀且第一次出现delimiter字符之间的object作为一组元素
  783.          *              'marker'        => 用户设定结果从marker之后按字母排序的第一个开始返回。
  784.          * )
  785.          * 其中 prefix,marker用来实现分页显示效果,参数的长度必须小于256字节。
  786.          * @throws OSS_Exception
  787.          * @author xiaobing.meng@alibaba-inc.com
  788.          * @since 2011-11-14
  789.          * @return ResponseCore
  790.          */
  791.         public function list_object($bucket,$options = NULL){
  792.                 //options
  793.                 $this->validate_options($options);
  794.  
  795.                 if(!$options){
  796.                         $options = array();
  797.                 }
  798.  
  799.                 //bucket
  800.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  801.  
  802.                 $options[self::OSS_BUCKET] = $bucket;
  803.                 $options[self::OSS_METHOD] = 'GET';
  804.                 $options[self::OSS_OBJECT] = '/';
  805.                 $options[self::OSS_HEADERS] = array(
  806.                 self::OSS_DELIMITER => isset($options[self::OSS_DELIMITER])?$options[self::OSS_DELIMITER]:'/',
  807.                 self::OSS_PREFIX => isset($options[self::OSS_PREFIX])?$options[self::OSS_PREFIX]:'',
  808.                 self::OSS_MAX_KEYS => isset($options[self::OSS_MAX_KEYS])?$options[self::OSS_MAX_KEYS]:self::OSS_MAX_KEYS_VALUE,
  809.                 self::OSS_MARKER => isset($options[self::OSS_MARKER])?$options[self::OSS_MARKER]:'',
  810.                 );
  811.                                
  812.                 $response = $this->auth ( $options );
  813.  
  814.                 return $response;
  815.  
  816.         }
  817.  
  818.         /**
  819.          * 创建目录(目录和文件的区别在于,目录最后增加'/')
  820.          * @param string $bucket
  821.          * @param string $object
  822.          * @param array $options
  823.          * @author xiaobing.meng@alibaba-inc.com
  824.          * @since 2011-11-14
  825.          * @return ResponseCore
  826.          */
  827.         public function create_object_dir($bucket,$object,$options = NULL){
  828.                 //options
  829.                 $this->validate_options($options);
  830.  
  831.                 if(!$options){
  832.                         $options = array();
  833.                 }
  834.  
  835.                 //bucket
  836.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  837.  
  838.                 //object
  839.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  840.  
  841.                 $options[self::OSS_BUCKET] = $bucket;
  842.                 $options[self::OSS_METHOD] = 'PUT';
  843.                 $options[self::OSS_OBJECT] = $object.'/';   //虚拟目录需要以'/结尾'
  844.                 $options[self::OSS_CONTENT_LENGTH] = array(self::OSS_CONTENT_LENGTH => 0);
  845.  
  846.                 $response = $this->auth ( $options );
  847.  
  848.                 return $response;
  849.         }
  850.  
  851.         /**
  852.          * 通过在http body中添加内容来上传文件,适合比较小的文件
  853.          * 根据api约定,需要在http header中增加content-length字段
  854.          * @param string $bucket (Required)
  855.          * @param string $object (Required)
  856.          * @param string $content (Required)
  857.          * @param array $options (Optional)
  858.          * @author xiaobing.meng@alibaba-inc.com
  859.          * @since 2011-11-14
  860.          * @return ResponseCore
  861.          */
  862.         public function upload_file_by_content($bucket,$object,$options = NULL){
  863.                 //options
  864.                 $this->validate_options($options);
  865.  
  866.                 if(!$options){
  867.                         $options = array();
  868.                 }
  869.  
  870.                 //bucket
  871.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  872.  
  873.                 //object
  874.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  875.  
  876.                 //内容校验
  877.                 $this->validate_content($options);
  878.  
  879.                        
  880.                 $objArr = explode('/', $object);
  881.                 $basename = array_pop($objArr);
  882.                 $extension = explode ( '.', $basename );
  883.                 $extension = array_pop ( $extension );
  884.                 $content_type = MimeTypes::get_mimetype(strtolower($extension));
  885.  
  886.                 $options[self::OSS_BUCKET] = $bucket;
  887.                 $options[self::OSS_METHOD] = 'PUT';
  888.                 $options[self::OSS_OBJECT] = $object;
  889.                
  890.                 if(!isset($options[self::OSS_LENGTH])){
  891.                         $options[self::OSS_CONTENT_LENGTH] = strlen($options[self::OSS_CONTENT]);
  892.                 }else{
  893.                         $options[self::OSS_CONTENT_LENGTH] = array(self::OSS_CONTENT_LENGTH => $options[self::OSS_LENGTH]);
  894.                 }
  895.                
  896.                 if(!isset($options[self::OSS_CONTENT_TYPE]) && isset($content_type) && !empty($content_type) ){
  897.                         $options[self::OSS_CONTENT_TYPE] = $content_type;
  898.                 }
  899.  
  900.                 $response = $this->auth ( $options );
  901.  
  902.                 return $response;
  903.         }
  904.  
  905.         /**
  906.          * 上传文件,适合比较大的文件
  907.          * @param string $bucket (Required)
  908.          * @param string $object (Required)
  909.          * @param string $file (Required)
  910.          * @param array $options (Optional)
  911.          * @author xiaobing.meng@alibaba-inc.com
  912.          * @since 2012-02-28
  913.          * @return ResponseCore
  914.          */
  915.         public function upload_file_by_file($bucket,$object,$file,$options = NULL){
  916.                 //options
  917.                 $this->validate_options($options);
  918.  
  919.                 if(!$options){
  920.                         $options = array();
  921.                 }
  922.  
  923.                 //bucket
  924.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  925.  
  926.                 //object
  927.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  928.  
  929.                 //file
  930.                 $this->is_empty($file, OSS_FILE_PATH_IS_NOT_ALLOWED_EMPTY);
  931.                
  932.                 if($this->chk_chinese($file)){
  933.                         $file = iconv('utf-8','gbk',$file);
  934.                 }
  935.                
  936.                 $options[self::OSS_FILE_UPLOAD] = $file;
  937.                
  938.                 if(!file_exists($options[self::OSS_FILE_UPLOAD])){
  939.                         throw new OSS_Exception($options[self::OSS_FILE_UPLOAD].OSS_FILE_NOT_EXIST);
  940.                 }
  941.                
  942.                 $filesize = filesize($options[self::OSS_FILE_UPLOAD]);
  943.                 $partsize = 1024 * 1024 ; //默认为 1M
  944.                
  945.                
  946.                 $extension = explode ( '.', $file );
  947.                 $extension = array_pop ( $extension );
  948.                 $content_type = MimeTypes::get_mimetype(strtolower($extension));
  949.                                
  950.                 $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
  951.                 $options[self::OSS_BUCKET] = $bucket;
  952.                 $options[self::OSS_OBJECT] = $object;
  953.                 $options[self::OSS_CONTENT_TYPE] = $content_type;
  954.                 $options[self::OSS_CONTENT_LENGTH] = $filesize;
  955.                                
  956.                 //return $file_part;
  957.                 $response = $this->auth($options);
  958.                 return $response;
  959.         }
  960.        
  961.        
  962.         /**
  963.          * 拷贝Object
  964.          * @param string $bucket (Required)
  965.          * @param string $from_object (Required)
  966.          * @param string $to_object (Required)
  967.          * @param string $options (Optional)
  968.          * @author xiaobing.meng@alibaba-inc.com
  969.          * @since 2011-12-21
  970.          * @return ResponseCore
  971.          */
  972.         public function copy_object($from_bucket,$from_object,$to_bucket,$to_object,$options = NULL){
  973.                 //options
  974.                 $this->validate_options($options);
  975.  
  976.                 if(!$options){
  977.                         $options = array();
  978.                 }
  979.  
  980.                 //from bucket
  981.                 $this->is_empty($from_bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  982.  
  983.                 //to bucket
  984.                 $this->is_empty($to_bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  985.  
  986.                 //from object
  987.                 $this->is_empty($from_object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  988.  
  989.                 //to object
  990.                 $this->is_empty($to_object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  991.  
  992.                 $options[self::OSS_BUCKET] = $to_bucket;
  993.                 $options[self::OSS_METHOD] = 'PUT';
  994.                 $options[self::OSS_OBJECT] = $to_object;
  995.                 $options[self::OSS_HEADERS] = array(self::OSS_OBJECT_COPY_SOURCE => '/'.$from_bucket.'/'.$from_object);
  996.  
  997.                 $response = $this->auth ( $options );
  998.  
  999.                 return $response;
  1000.         }
  1001.  
  1002.         /**
  1003.          * 获得object的meta信息
  1004.          * @param string $bucket (Required)
  1005.          * @param string $object (Required)
  1006.          * @param string $options (Optional)
  1007.          * @author xiaobing.meng@alibaba-inc.com
  1008.          * @since 2011-11-14
  1009.          * @return ResponseCore
  1010.          */
  1011.         public function get_object_meta($bucket,$object,$options = NULL){
  1012.                 //options
  1013.                 $this->validate_options($options);
  1014.  
  1015.                 if(!$options){
  1016.                         $options = array();
  1017.                 }
  1018.  
  1019.                 //bucket
  1020.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1021.  
  1022.                 //object
  1023.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1024.  
  1025.                 $options[self::OSS_BUCKET] = $bucket;
  1026.                 $options[self::OSS_METHOD] = 'HEAD';
  1027.                 $options[self::OSS_OBJECT] = $object;
  1028.  
  1029.                 $response = $this->auth ( $options );
  1030.  
  1031.                 return $response;
  1032.         }
  1033.  
  1034.         /**
  1035.          * 删除object
  1036.          * @param string $bucket(Required)
  1037.          * @param string $object (Required)
  1038.          * @param array $options (Optional)
  1039.          * @author xiaobing.meng@alibaba-inc.com
  1040.          * @since 2011-11-14
  1041.          * @return ResponseCore
  1042.          */
  1043.         public function delete_object($bucket,$object,$options = NULL){
  1044.                 //options
  1045.                 $this->validate_options($options);
  1046.  
  1047.                 if(!$options){
  1048.                         $options = array();
  1049.                 }
  1050.  
  1051.                 //bucket
  1052.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1053.  
  1054.                 //object
  1055.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1056.  
  1057.                 $options[self::OSS_BUCKET] = $bucket;
  1058.                 $options[self::OSS_METHOD] = 'DELETE';
  1059.                 $options[self::OSS_OBJECT] = $object;
  1060.  
  1061.                 $response = $this->auth ( $options );
  1062.  
  1063.                 return $response;
  1064.         }
  1065.        
  1066.         /**
  1067.          * 批量删除objects
  1068.          * @param string $bucket(Required)
  1069.          * @param array $objects (Required)
  1070.          * @param array $options (Optional)
  1071.          * @author xiaobing.meng@alibaba-inc.com
  1072.          * @since 2012-03-09
  1073.          * @return ResponseCore
  1074.          */
  1075.         public function delete_objects($bucket,$objects,$options = null){
  1076.                 //options
  1077.                 $this->validate_options($options);
  1078.  
  1079.                 if(!$options){
  1080.                         $options = array();
  1081.                 }
  1082.  
  1083.                 //bucket
  1084.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1085.  
  1086.                 //objects
  1087.                 if(!is_array($objects) || !$objects){
  1088.                         throw new OSS_Exception('The ' . __FUNCTION__ . ' method requires the "objects" option to be set as an array.');
  1089.                 }
  1090.                
  1091.                 $options[self::OSS_METHOD] = self::OSS_HTTP_POST;
  1092.                 $options[self::OSS_BUCKET] = $bucket;
  1093.                 $options[self::OSS_OBJECT] = '/';
  1094.                 $options[self::OSS_SUB_RESOURCE] = 'delete';
  1095.                 $options[self::OSS_CONTENT_TYPE] = 'application/xml';
  1096.                
  1097.                 $xml = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><Delete></Delete>');
  1098.                
  1099.                 // Quiet mode?
  1100.                 if (isset($options['quiet'])){
  1101.                         $quiet = 'false';
  1102.                         if (is_bool($options['quiet'])) { //Boolean
  1103.                                 $quiet = $options['quiet'] ? 'true' : 'false';
  1104.                         }elseif (is_string($options['quiet'])){ // String
  1105.                                 $quiet = ($options['quiet'] === 'true') ? 'true' : 'false';
  1106.                         }
  1107.  
  1108.                         $xml->addChild('Quiet', $quiet);
  1109.                 }
  1110.                                
  1111.                 // Add the objects
  1112.                 foreach ($objects as $object){
  1113.                         $xobject = $xml->addChild('Object');
  1114.                         $object = $this->s_replace($object);           
  1115.                         $xobject->addChild('Key', $object);
  1116.                 }              
  1117.  
  1118.                 $options[self::OSS_CONTENT] = $xml->asXML();           
  1119.                        
  1120.                 return $this->auth($options);
  1121.         }
  1122.  
  1123.         /**
  1124.          * 获得Object内容
  1125.          * @param string $bucket(Required)
  1126.          * @param string $object (Required)
  1127.          * @param array $options (Optional)
  1128.          * @author xiaobing.meng@alibaba-inc.com
  1129.          * @since 2011-11-14
  1130.          * @return ResponseCore
  1131.          */
  1132.         public function get_object($bucket,$object,$options = NULL){
  1133.                 //options
  1134.                 $this->validate_options($options);
  1135.  
  1136.                 if(!$options){
  1137.                         $options = array();
  1138.                 }
  1139.  
  1140.                 //bucket
  1141.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1142.  
  1143.                 //object
  1144.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1145.                
  1146.                 if(isset($options[self::OSS_FILE_DOWNLOAD]) && $this->chk_chinese($options[self::OSS_FILE_DOWNLOAD])){
  1147.                         $options[self::OSS_FILE_DOWNLOAD] = iconv('utf-8','gbk',$options[self::OSS_FILE_DOWNLOAD]);
  1148.                 }
  1149.  
  1150.                 $options[self::OSS_BUCKET] = $bucket;
  1151.                 $options[self::OSS_METHOD] = 'GET';
  1152.                 $options[self::OSS_OBJECT] = $object;
  1153.                
  1154.                 if(isset($options['lastmodified'])){
  1155.                         $options[self::OSS_HEADERS][self::OSS_IF_MODIFIED_SINCE] = $options['lastmodified'];
  1156.             unset($options['lastmodified']);
  1157.                 }
  1158.                
  1159.                 if(isset($options['etag'])){
  1160.                         $options[self::OSS_HEADERS][self::OSS_IF_NONE_MATCH] = $options['etag'];
  1161.             unset($options['etag']);
  1162.                 }
  1163.                
  1164.                 if(isset($options['range'])){
  1165.                         $options[self::OSS_HEADERS][self::OSS_RANGE] = 'bytes=' . $options['range'];
  1166.             unset($options['range']);
  1167.                 }
  1168.                
  1169.                 return $this->auth ( $options );
  1170.         }
  1171.  
  1172.         /**
  1173.          * 检测Object是否存在
  1174.          * @param string $bucket(Required)
  1175.          * @param string $object (Required)
  1176.          * @param array $options (Optional)
  1177.          * @author xiaobing.meng@alibaba-inc.com
  1178.          * @since 2011-11-14
  1179.          * @return boolean
  1180.          */
  1181.         public function is_object_exist($bucket,$object,$options = NULL){
  1182.                 //options
  1183.                 $this->validate_options($options);
  1184.  
  1185.                 if(!$options){
  1186.                         $options = array();
  1187.                 }
  1188.  
  1189.                 //bucket
  1190.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1191.  
  1192.                 //object
  1193.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1194.  
  1195.                 $options[self::OSS_BUCKET] = $bucket;
  1196.                 $options[self::OSS_METHOD] = 'GET';
  1197.                 $options[self::OSS_OBJECT] = $object;
  1198.  
  1199.                 $response = $this->get_object_meta($bucket, $object,$options);
  1200.  
  1201.                 return $response;
  1202.         }
  1203.  
  1204.  
  1205.         /*%******************************************************************************************************%*/
  1206.         //Multi Part相关操作       
  1207.        
  1208.         /**
  1209.          * 计算文件可以分成多少个part,以及每个part的长度以及起始位置
  1210.          * 方法必须在 <upload_part()>中调用
  1211.          *
  1212.          * @param integer $filesize (Required) 文件大小
  1213.          * @param integer $part_size (Required) part大小,默认5M
  1214.          * @return array An array 包含 key-value 键值对. Key 为 `seekTo` 和 `length`.
  1215.          */    
  1216.         public function get_multipart_counts($filesize, $part_size = 5242880 ){
  1217.                 $i = 0;
  1218.                 $sizecount = $filesize;
  1219.                 $values = array();
  1220.  
  1221.                 if((integer)$part_size <= 5242880){
  1222.                         $part_size = 5242880;   //5M
  1223.                 }elseif ((integer)$part_size > 524288000){
  1224.                         $part_size = 524288000; //500M
  1225.                 }else{
  1226.                         $part_size = 52428800; //50M
  1227.                 }              
  1228.                
  1229.                 while ($sizecount > 0)
  1230.                 {
  1231.                         $sizecount -= $part_size;
  1232.                         $values[] = array(
  1233.                                 self::OSS_SEEK_TO => ($part_size * $i),
  1234.                                 self::OSS_LENGTH => (($sizecount > 0) ? $part_size : ($sizecount + $part_size)),
  1235.                         );
  1236.                         $i++;
  1237.                 }
  1238.  
  1239.                 return $values;        
  1240.         }
  1241.        
  1242.         /**
  1243.          * 初始化multi-part upload,并且返回uploadId
  1244.          * @param string $bucket (Required) Bucket名称
  1245.          * @param string $object (Required) Object名称
  1246.          * @param array $options (Optional) Key-Value数组,其中可以包括以下的key
  1247.          * @return ResponseCore
  1248.          */
  1249.         public function initiate_multipart_upload($bucket,$object,$options = NULL){
  1250.                 //options
  1251.                 $this->validate_options($options);
  1252.  
  1253.                 if(!$options){
  1254.                         $options = array();
  1255.                 }
  1256.  
  1257.                 //bucket
  1258.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1259.  
  1260.                 //object
  1261.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1262.  
  1263.                 // 发送请求
  1264.                 $options[self::OSS_METHOD] = self::OSS_HTTP_POST;
  1265.                 $options[self::OSS_BUCKET] = $bucket;
  1266.                 $options[self::OSS_OBJECT] = $object;
  1267.                 $options[self::OSS_SUB_RESOURCE] = 'uploads';
  1268.                 $options[self::OSS_CONTENT] = '';
  1269.                 //$options[self::OSS_CONTENT_LENGTH] = 0;
  1270.                 $options[self::OSS_HEADERS] = array(self::OSS_CONTENT_TYPE => 'application/octet-stream');
  1271.  
  1272.                 $response = $this->auth ( $options );
  1273.  
  1274.                 return $response;              
  1275.         }
  1276.        
  1277.         /**
  1278.          * 上传part
  1279.          * @param string $bucket (Required) Bucket名称
  1280.          * @param string $object (Required) Object名称
  1281.          * @param string $upload_id (Required) uploadId
  1282.          * @param array $options (Optional) Key-Value数组,其中可以包括以下的key
  1283.          * @return ResponseCore
  1284.          */
  1285.         public function upload_part($bucket, $object, $upload_id, $options = null){
  1286.                 //options
  1287.                 $this->validate_options($options);
  1288.  
  1289.                 if(!$options){
  1290.                         $options = array();
  1291.                 }
  1292.  
  1293.                 //bucket
  1294.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1295.  
  1296.                 //object
  1297.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1298.  
  1299.                 if (!isset($options[self::OSS_FILE_UPLOAD]) || !isset($options['partNumber'])){
  1300.                         throw new OSS_Exception('The `fileUpload` and `partNumber` options are both required in ' . __FUNCTION__ . '().');
  1301.                 }
  1302.                                                
  1303.                 $options[self::OSS_METHOD] = self::OSS_HTTP_PUT;
  1304.                 $options[self::OSS_BUCKET] = $bucket;
  1305.                 $options[self::OSS_OBJECT] = $object;
  1306.                 $options[self::OSS_UPLOAD_ID] = $upload_id;    
  1307.                
  1308.                 if(isset($options[self::OSS_LENGTH])){
  1309.                         $options[self::OSS_CONTENT_LENGTH] =  $options[self::OSS_LENGTH];
  1310.                 }
  1311.  
  1312.                 return $this->auth($options);
  1313.         }
  1314.        
  1315.         /**
  1316.          * list part
  1317.          * @param string $bucket (Required) Bucket名称
  1318.          * @param string $object (Required) Object名称
  1319.          * @param string $upload_id (Required) uploadId
  1320.          * @param array $options (Optional) Key-Value数组,其中可以包括以下的key
  1321.          * @return ResponseCore
  1322.          */    
  1323.         public function list_parts($bucket, $object, $upload_id, $options = null){
  1324.                 //options
  1325.                 $this->validate_options($options);
  1326.  
  1327.                 if(!$options){
  1328.                         $options = array();
  1329.                 }
  1330.  
  1331.                 //bucket
  1332.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1333.  
  1334.                 //object
  1335.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1336.  
  1337.                 $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
  1338.                 $options[self::OSS_BUCKET] = $bucket;
  1339.                 $options[self::OSS_OBJECT] = $object;
  1340.                 $options[self::OSS_UPLOAD_ID] = $upload_id;
  1341.                 $options[self::OSS_QUERY_STRING] = array();
  1342.  
  1343.                 foreach (array('max-parts', 'part-number-marker') as $param){
  1344.                         if (isset($options[$param])){
  1345.                                 $options[self::OSS_QUERY_STRING][$param] = $options[$param];
  1346.                                 unset($options[$param]);
  1347.                         }
  1348.                 }      
  1349.  
  1350.                 return $this->auth($options);
  1351.         }
  1352.        
  1353.         /**
  1354.          * 中止上传mulit-part upload
  1355.          * @param string $bucket (Required) Bucket名称
  1356.          * @param string $object (Required) Object名称
  1357.          * @param string $upload_id (Required) uploadId
  1358.          * @param array $options (Optional) Key-Value数组,其中可以包括以下的key
  1359.          * @return ResponseCore
  1360.          */    
  1361.         public function abort_multipart_upload($bucket, $object, $upload_id, $options = NULL){
  1362.                 //options
  1363.                 $this->validate_options($options);
  1364.  
  1365.                 if(!$options){
  1366.                         $options = array();
  1367.                 }
  1368.  
  1369.                 //bucket
  1370.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1371.  
  1372.                 //object
  1373.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1374.  
  1375.                 $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE;
  1376.                 $options[self::OSS_BUCKET] = $bucket;
  1377.                 $options[self::OSS_OBJECT] = $object;
  1378.                 $options[self::OSS_UPLOAD_ID] = $upload_id;
  1379.                
  1380.                 return $this->auth($options);
  1381.         }
  1382.        
  1383.         /**
  1384.          * 完成multi-part上传
  1385.          * @param string $bucket (Required) Bucket名称
  1386.          * @param string $object (Required) Object名称
  1387.          * @param string $upload_id (Required) uploadId
  1388.          * @param string $parts xml格式文件
  1389.          * @param array $options (Optional) Key-Value数组,其中可以包括以下的key
  1390.          * @return ResponseCore
  1391.          */    
  1392.         public function complete_multipart_upload($bucket, $object, $upload_id, $parts, $options = NULL){
  1393.                 //options
  1394.                 $this->validate_options($options);
  1395.  
  1396.                 if(!$options){
  1397.                         $options = array();
  1398.                 }
  1399.  
  1400.                 //bucket
  1401.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1402.  
  1403.                 //object
  1404.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1405.                
  1406.                 $options[self::OSS_METHOD] = self::OSS_HTTP_POST;
  1407.                 $options[self::OSS_BUCKET] = $bucket;
  1408.                 $options[self::OSS_OBJECT] = $object;
  1409.                 $options[self::OSS_UPLOAD_ID] = $upload_id;
  1410.                 $options[self::OSS_CONTENT_TYPE] = 'application/xml';
  1411.  
  1412.                
  1413.                 if(is_string($parts)){
  1414.                         $options[self::OSS_CONTENT] = $parts;
  1415.                 }else if($parts instanceof SimpleXMLElement){
  1416.                         $options[self::OSS_CONTENT] = $parts->asXML();
  1417.                 }else if((is_array($parts) || $parts instanceof ResponseCore)){
  1418.                         $xml = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><CompleteMultipartUpload></CompleteMultipartUpload>');
  1419.  
  1420.                         if (is_array($parts)){
  1421.                                 //生成关联的xml
  1422.                                 foreach ($parts as $node){
  1423.                                         $part = $xml->addChild('Part');
  1424.                                         $part->addChild('PartNumber', $node['PartNumber']);
  1425.                                         $part->addChild('ETag', $node['ETag']);
  1426.                                 }
  1427.                         }elseif ($parts instanceof ResponseCore){
  1428.                                 foreach ($parts->body->Part as $node){
  1429.                                         $part = $xml->addChild('Part');
  1430.                                         $part->addChild('PartNumber', (string) $node->PartNumber);
  1431.                                         $part->addChild('ETag', (string) $node->ETag);
  1432.                                 }
  1433.                         }
  1434.  
  1435.                         $options[self::OSS_CONTENT] = $xml->asXML();                   
  1436.                 }
  1437.        
  1438.                 return $this->auth($options);          
  1439.         }
  1440.        
  1441.         /**
  1442.          * 列出multipart上传
  1443.          * @param string $bucket (Requeired) bucket
  1444.          * @param array $options (Optional) 关联数组
  1445.          * @author xiaobing.meng@alibaba-inc.com
  1446.          * @since 2012-03-05
  1447.          * @return ResponseCore
  1448.          */
  1449.         public function list_multipart_uploads($bucket, $options = null){
  1450.                 //options
  1451.                 $this->validate_options($options);
  1452.  
  1453.                 if(!$options){
  1454.                         $options = array();
  1455.                 }
  1456.  
  1457.                 //bucket
  1458.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1459.  
  1460.                 $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
  1461.                 $options[self::OSS_BUCKET] = $bucket;
  1462.                 $options[self::OSS_OBJECT] = '/';
  1463.                 $options[self::OSS_SUB_RESOURCE] = 'uploads';
  1464.  
  1465.                 foreach (array('key-marker', 'max-uploads', 'upload-id-marker') as $param){
  1466.                         if (isset($options[$param])){
  1467.                                 $options[self::OSS_QUERY_STRING][$param] = $options[$param];
  1468.                                 unset($options[$param]);
  1469.                         }
  1470.                 }
  1471.                                
  1472.                 return $this->auth($options);
  1473.         }
  1474.        
  1475.         /**
  1476.          * multipart上传统一封装,从初始化到完成multipart,以及出错后中止动作
  1477.          * @param unknown_type $bucket
  1478.          * @param unknown_type $object
  1479.          * @param unknown_type $options
  1480.          * @author xiaobing.meng@alibaba-inc.com
  1481.          * @since 2012-03-05
  1482.          * @return ResponseCore
  1483.          */
  1484.         public function create_mpu_object($bucket, $object, $options = null){
  1485.                 //options
  1486.                 $this->validate_options($options);
  1487.  
  1488.                 if(!$options){
  1489.                         $options = array();
  1490.                 }
  1491.  
  1492.                 //bucket
  1493.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1494.  
  1495.                 //object
  1496.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1497.  
  1498.                 if(isset($options[self::OSS_LENGTH])){
  1499.                         $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH];
  1500.                         unset($options[self::OSS_LENGTH]);
  1501.                 }
  1502.                
  1503.                 if(isset($options[self::OSS_FILE_UPLOAD])){
  1504.                         if($this->chk_chinese($options[self::OSS_FILE_UPLOAD])){
  1505.                                 $options[self::OSS_FILE_UPLOAD] = mb_convert_encoding($options[self::OSS_FILE_UPLOAD],'UTF-8');
  1506.                         }                      
  1507.                 }
  1508.                
  1509.                 if(!isset($options[self::OSS_FILE_UPLOAD])){
  1510.                         throw new OSS_Exception('The `fileUpload` option is required in ' . __FUNCTION__ . '().');
  1511.                 }elseif (is_resource($options[self::OSS_FILE_UPLOAD])){                                
  1512.                         $upload_position = isset($options[self::OSS_SEEK_TO]) ? (integer) $options[self::OSS_SEEK_TO] : ftell($options[self::OSS_FILE_UPLOAD]);
  1513.                         $upload_filesize = isset($options[self::OSS_CONTENT_TYPE]) ? (integer) $options[self::OSS_CONTENT_TYPE] : null;
  1514.  
  1515.                         if (!isset($upload_filesize) && $upload_position !== false){
  1516.                                 $stats = fstat($options[self::OSS_FILE_UPLOAD]);
  1517.  
  1518.                                 if ($stats && $stats[self::OSS_SIZE] >= 0){
  1519.                                         $upload_filesize = $stats[self::OSS_SIZE] - $upload_position;
  1520.                                 }
  1521.                         }                      
  1522.                 }else{
  1523.                         $upload_position = isset($options[self::OSS_SEEK_TO]) ? (integer) $options[self::OSS_SEEK_TO] : 0;
  1524.  
  1525.                         if (isset($options[self::OSS_CONTENT_TYPE])){
  1526.                                 $upload_filesize = (integer) $options[self::OSS_CONTENT_TYPE];
  1527.                         }
  1528.                         else{
  1529.                                 $upload_filesize = filesize($options[self::OSS_FILE_UPLOAD]);
  1530.  
  1531.                                 if ($upload_filesize !== false){
  1532.                                         $upload_filesize -= $upload_position;
  1533.                                 }
  1534.                         }                      
  1535.                 }
  1536.                
  1537.                 if ($upload_position === false || !isset($upload_filesize) || $upload_filesize === false || $upload_filesize < 0){
  1538.                         throw new OSS_Exception('The size of `fileUpload` cannot be determined in ' . __FUNCTION__ . '().');
  1539.                 }
  1540.                
  1541.                 // 处理partSize
  1542.                 if (isset($options[self::OSS_PART_SIZE])){
  1543.                         // 小于5M
  1544.                         if ((integer) $options[self::OSS_PART_SIZE] <= 5242880){
  1545.                                 $options[self::OSS_PART_SIZE] = 5242880; // 5 MB
  1546.                         }
  1547.                         // 大于500M
  1548.                         elseif ((integer) $options[self::OSS_PART_SIZE] > 524288000){
  1549.                                 $options[self::OSS_PART_SIZE] = 524288000; // 500 MB
  1550.                         }
  1551.                 }
  1552.                 else{
  1553.                         $options[self::OSS_PART_SIZE] = 52428800; // 50 MB
  1554.                 }
  1555.  
  1556.                 // 如果上传的文件小于partSize,则直接使用普通方式上传
  1557.                 if ($upload_filesize < $options[self::OSS_PART_SIZE] && !isset($options['uploadId'])){
  1558.                         return $this->upload_file_by_file($bucket, $object, $options[self::OSS_FILE_UPLOAD]);
  1559.                 }      
  1560.  
  1561.                 // 初始化multipart
  1562.                 if (isset($options['uploadId'])){
  1563.                         $upload_id = $options['uploadId'];
  1564.                 }else{
  1565.                         //初始化
  1566.                         $upload = $this->initiate_multipart_upload($bucket, $object);
  1567.                        
  1568.                         if (!$upload->isOK()){
  1569.                                 throw new OSS_Exception('Init multi-part upload failed...');
  1570.                         }
  1571.                         $xml = new SimpleXmlIterator($upload->body);
  1572.                         $uploadId = (string)$xml->UploadId;
  1573.                 }              
  1574.  
  1575.                 // 或的分片
  1576.                 $pieces = $this->get_multipart_counts($upload_filesize, (integer) $options[self::OSS_PART_SIZE]);
  1577.  
  1578.                 $response_upload_part = array();
  1579.                 foreach ($pieces as $i => $piece){
  1580.                         $response_upload_part[] = $this->upload_part($bucket, $object, $uploadId, array(
  1581.                                 //'expect' => '100-continue',
  1582.                                 self::OSS_FILE_UPLOAD => $options[self::OSS_FILE_UPLOAD],
  1583.                                 'partNumber' => ($i + 1),
  1584.                                 self::OSS_SEEK_TO => $upload_position + (integer) $piece[self::OSS_SEEK_TO],
  1585.                                 self::OSS_LENGTH => (integer) $piece[self::OSS_LENGTH],
  1586.                         ));
  1587.                 }
  1588.                
  1589.                 $upload_parts = array();
  1590.                 $upload_part_result = true;
  1591.                
  1592.                 foreach ($response_upload_part as $i=>$response){
  1593.                         $upload_part_result = $upload_part_result && $response->isOk();
  1594.                 }
  1595.                
  1596.                 if(!$upload_part_result){
  1597.                         throw new OSS_Exception('any part upload failed...,pls try again');
  1598.                 }
  1599.                
  1600.                 foreach ($response_upload_part as $i=>$response){
  1601.                         $upload_parts[] = array(
  1602.                                 'PartNumber' => ($i + 1),
  1603.                             'ETag' => (string) $response->header['etag']
  1604.                         );             
  1605.                 }
  1606.                                
  1607.                 return $this->complete_multipart_upload($bucket, $object, $uploadId, $upload_parts);
  1608.         }
  1609.        
  1610.        
  1611.         /**
  1612.          * 通过Multi-Part方式上传整个目录,其中的object默认为文件名
  1613.          * @param string $bucket (Required)
  1614.          * @param string $dir  (Required) 必选
  1615.          * @param boolean $recursive (Optional) 是否递归,如果为true,则递归读取所有目录,默认为不递归读取
  1616.          * @param string $exclude 需要过滤的文件
  1617.          * @param array $options (Optional) 关联数组
  1618.          * @author xiaobing.meng@alibaba-inc.com
  1619.          * @since 2012-03-05
  1620.          * @return ResponseCore
  1621.          */
  1622.         public function create_mtu_object_by_dir($bucket,$dir,$recursive = false,$exclude = ".|..|.svn",$options = null){
  1623.                 //options
  1624.                 $this->validate_options($options);
  1625.  
  1626.                 //bucket
  1627.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1628.  
  1629.                 if($this->chk_chinese($dir)){
  1630.                         $dir = iconv('utf-8','gbk',$dir);
  1631.                 }
  1632.                
  1633.                 //判断是否目录
  1634.                 if(!is_dir($dir)){
  1635.                         throw new OSS_Exception($dir.' is not a directory...,pls check it');
  1636.                 }
  1637.                
  1638.                 $file_list_array = $this->read_dir($dir,$exclude,$recursive);
  1639.                                
  1640.                 if(!$file_list_array){
  1641.                         throw new OSS_Exception($dir.' is empty...');
  1642.                 }
  1643.                
  1644.                 $index = 1;
  1645.                
  1646.                 foreach ($file_list_array as $item){
  1647.                         $options = array(
  1648.                                 self::OSS_FILE_UPLOAD => $item['path'],
  1649.                                 self::OSS_PART_SIZE => 5242880,
  1650.                         );                     
  1651.                        
  1652.                         echo $index++.". ";
  1653.                         $response = $this->create_mpu_object($bucket, $item['file'],$options);
  1654.                         if($response->isOK()){
  1655.                                 echo "Upload file {".$item['path']." } successful..\n";
  1656.                         }else{
  1657.                                 echo "Upload file {".$item['path']." } failed..\n";
  1658.                                 continue;
  1659.                         }
  1660.                 }
  1661.         }
  1662.        
  1663.                
  1664.         /*%******************************************************************************************************%*/
  1665.         //Object Group相关操作
  1666.  
  1667.         /**
  1668.          * 创建Object Group
  1669.          * @param string $object_group (Required)  Object Group名称
  1670.          * @param string $bucket (Required) Bucket名称
  1671.          * @param array $object_arry (Required) object数组,所有的object必须在同一个bucket下
  1672.          * 其中$object 数组的格式如下:
  1673.          * $object = array(
  1674.          *              $object1,
  1675.          *              $object2,
  1676.          *              ...
  1677.          * )
  1678.          * @param array $options (Optional)
  1679.          * @author xiaobing.meng@alibaba-inc.com
  1680.          * @since 2011-11-14
  1681.          * @return ResponseCore
  1682.          */
  1683.         public function create_object_group($bucket,$object_group  ,$object_arry,$options = NULL){
  1684.                 //options
  1685.                 $this->validate_options($options);
  1686.  
  1687.                 //bucket
  1688.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1689.  
  1690.                 //object group
  1691.                 $this->is_empty($object_group,OSS_OBJECT_GROUP_IS_NOT_ALLOWED_EMPTY);
  1692.  
  1693.                 $options[self::OSS_BUCKET] = $bucket;
  1694.                 $options[self::OSS_METHOD] = 'POST';
  1695.                 $options[self::OSS_OBJECT] = $object_group;
  1696.                 $options[self::OSS_CONTENT_TYPE] = 'txt/xml';  //重设Content-Type
  1697.                 $options[self::OSS_SUB_RESOURCE] = 'group';        //设置?group
  1698.                 $options[self::OSS_CONTENT] = $this->make_object_group_xml($bucket,$object_arry);   //格式化xml
  1699.  
  1700.                 $response = $this->auth ( $options );
  1701.  
  1702.                 return $response;
  1703.         }
  1704.  
  1705.         /**
  1706.          * 获取Object Group
  1707.          * @param string $object_group (Required)
  1708.          * @param string $bucket        (Required)
  1709.          * @param array $options        (Optional)
  1710.          * @author xiaobing.meng@alibaba-inc.com
  1711.          * @since 2011-11-14
  1712.          * @return ResponseCore
  1713.          */
  1714.         public function get_object_group($bucket,$object_group,$options = NULL){
  1715.                 //options
  1716.                 $this->validate_options($options);
  1717.  
  1718.                 //bucket
  1719.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1720.  
  1721.                 //object group
  1722.                 $this->is_empty($object_group,OSS_OBJECT_GROUP_IS_NOT_ALLOWED_EMPTY);
  1723.  
  1724.                 $options[self::OSS_BUCKET] = $bucket;
  1725.                 $options[self::OSS_METHOD] = 'GET';
  1726.                 $options[self::OSS_OBJECT] = $object_group;
  1727.                 //$options[self::OSS_OBJECT_GROUP] = true;         //设置?group
  1728.                 //$options[self::OSS_CONTENT_TYPE] = 'txt/xml';  //重设Content-Type
  1729.                 $options[self::OSS_HEADERS] = array(self::OSS_OBJECT_GROUP => self::OSS_OBJECT_GROUP);  //header中的x-oss-file-group不能为空,否则返回值错误
  1730.  
  1731.                 $response = $this->auth ( $options );
  1732.  
  1733.                 return $response;
  1734.         }
  1735.  
  1736.         /**
  1737.          * 获取Object Group 的Object List信息
  1738.          * @param string $object_group (Required)
  1739.          * @param string $bucket        (Required)
  1740.          * @param array $options        (Optional)
  1741.          * @author xiaobing.meng@alibaba-inc.com
  1742.          * @since 2011-11-14
  1743.          * @return ResponseCore
  1744.          */
  1745.         public function get_object_group_index($bucket,$object_group,$options = NULL){
  1746.                 //options
  1747.                 $this->validate_options($options);
  1748.  
  1749.                 //bucket
  1750.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1751.  
  1752.                 //object group
  1753.                 $this->is_empty($object_group,OSS_OBJECT_GROUP_IS_NOT_ALLOWED_EMPTY);
  1754.  
  1755.                 $options[self::OSS_BUCKET] = $bucket;
  1756.                 $options[self::OSS_METHOD] = 'GET';
  1757.                 $options[self::OSS_OBJECT] = $object_group;
  1758.                 $options[self::OSS_CONTENT_TYPE] = 'application/xml';  //重设Content-Type
  1759.                 //$options[self::OSS_OBJECT_GROUP] = true;         //设置?group
  1760.                 $options[self::OSS_HEADERS] = array(self::OSS_OBJECT_GROUP => self::OSS_OBJECT_GROUP);
  1761.  
  1762.                 $response = $this->auth ( $options );
  1763.  
  1764.                 return $response;
  1765.         }
  1766.  
  1767.         /**
  1768.          * 获得object group的meta信息
  1769.          * @param string $bucket (Required)
  1770.          * @param string $object_group (Required)
  1771.          * @param string $options (Optional)
  1772.          * @author xiaobing.meng@alibaba-inc.com
  1773.          * @since 2011-11-14
  1774.          * @return ResponseCore
  1775.          */
  1776.         public function get_object_group_meta($bucket,$object_group,$options = NULL){
  1777.                 //options
  1778.                 $this->validate_options($options);
  1779.  
  1780.                 if(!$options){
  1781.                         $options = array();
  1782.                 }
  1783.  
  1784.                 //bucket
  1785.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1786.  
  1787.                 //object group
  1788.                 $this->is_empty($object_group,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1789.  
  1790.                 $options[self::OSS_BUCKET] = $bucket;
  1791.                 $options[self::OSS_METHOD] = 'HEAD';
  1792.                 $options[self::OSS_OBJECT] = $object_group;
  1793.                 $options[self::OSS_CONTENT_TYPE] = 'application/xml';  //重设Content-Type
  1794.                 //$options[self::OSS_SUB_RESOURCE] = 'group';      //设置?group
  1795.                 $options[self::OSS_HEADERS] = array(self::OSS_OBJECT_GROUP => self::OSS_OBJECT_GROUP);
  1796.  
  1797.                 $response = $this->auth ( $options );
  1798.  
  1799.                 return $response;
  1800.         }
  1801.  
  1802.         /**
  1803.          * 删除Object Group
  1804.          * @param string $bucket(Required)
  1805.          * @param string $object_group (Required)
  1806.          * @param array $options (Optional)
  1807.          * @author xiaobing.meng@alibaba-inc.com
  1808.          * @since 2011-11-14
  1809.          * @return ResponseCore
  1810.          */
  1811.         public function delete_object_group($bucket,$object_group,$options = NULL){
  1812.                 //options
  1813.                 $this->validate_options($options);
  1814.  
  1815.                 if(!$options){
  1816.                         $options = array();
  1817.                 }
  1818.  
  1819.                 //bucket
  1820.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1821.  
  1822.                 //object group
  1823.                 $this->is_empty($object_group,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1824.  
  1825.                 $options[self::OSS_BUCKET] = $bucket;
  1826.                 $options[self::OSS_METHOD] = 'DELETE';
  1827.                 $options[self::OSS_OBJECT] = $object_group;
  1828.  
  1829.                 $response = $this->auth ( $options );
  1830.  
  1831.                 return $response;
  1832.         }
  1833.  
  1834.  
  1835.         /*%******************************************************************************************************%*/
  1836.         //带签名的url相关
  1837.  
  1838.         /**
  1839.          * 获取带签名的url
  1840.          * @param string $bucket (Required)
  1841.          * @param string $object (Required)
  1842.          * @param int    $timeout (Optional)
  1843.          * @param array $options (Optional)
  1844.          * @author xiaobing.meng@alibaba-inc.com
  1845.          * @since 2011-12-21
  1846.          * @return string
  1847.          */
  1848.         public function get_sign_url($bucket,$object,$timeout = 60,$options = NULL){
  1849.                 //options
  1850.                 $this->validate_options($options);
  1851.  
  1852.                 if(!$options){
  1853.                         $options = array();
  1854.                 }
  1855.  
  1856.                 //bucket
  1857.                 $this->is_empty($bucket,OSS_BUCKET_IS_NOT_ALLOWED_EMPTY);
  1858.  
  1859.                 //object
  1860.                 $this->is_empty($object,OSS_OBJECT_IS_NOT_ALLOWED_EMPTY);
  1861.  
  1862.                 $options[self::OSS_BUCKET] = $bucket;
  1863.                 $options[self::OSS_OBJECT] = $object;
  1864.                 $options[self::OSS_METHOD] = self::OSS_HTTP_GET;
  1865.                 $options[self::OSS_CONTENT_TYPE] = '';
  1866.  
  1867.                 $timeout = time() + $timeout;
  1868.                 $options[self::OSS_EXPIRES] = $timeout;
  1869.                 $options[self::OSS_DATE] = $timeout;
  1870.  
  1871.                 return $this->auth($options);
  1872.         }
  1873.  
  1874.         /*%******************************************************************************************************%*/
  1875.         //日志相关
  1876.  
  1877.         /**
  1878.          * 记录日志
  1879.          * @param string $msg (Required)
  1880.          * @throws OSS_Exception
  1881.          * @author xiaobing.meng@alibaba-inc.com
  1882.          * @since 2011-12-27
  1883.          * @return void
  1884.          */
  1885.         private function log($msg){
  1886.                 if(defined('ALI_LOG_PATH') ){
  1887.                         $log_path = ALI_LOG_PATH;
  1888.                         if(empty($log_path) || !file_exists($log_path)){
  1889.                                 throw new OSS_Exception($log_path.OSS_LOG_PATH_NOT_EXIST);
  1890.                         }
  1891.                 }else{
  1892.                         $log_path = dirname(__FILE__).DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR;
  1893.                 }
  1894.                
  1895.                 //检测日志目录是否存在
  1896.                 if(!file_exists($log_path)){
  1897.                         throw new OSS_Exception(OSS_LOG_PATH_NOT_EXIST);
  1898.                 }
  1899.  
  1900.                 $log_name = $log_path.'oss_sdk_php_'.date('Y-m-d').'.log';
  1901.  
  1902.                 if(ALI_DISPLAY_LOG){
  1903.                         echo $msg."\n<br/>";
  1904.                 }
  1905.                
  1906.                 if(ALI_LOG){
  1907.                         if(!error_log(date('Y-m-d H:i:s')." : ".$msg."\n", 3,$log_name)){
  1908.                                 throw new OSS_Exception(OSS_WRITE_LOG_TO_FILE_FAILED);
  1909.                         }
  1910.                 }
  1911.         }
  1912.  
  1913.  
  1914.         /*%******************************************************************************************************%*/
  1915.         //工具类相关
  1916.  
  1917.         /**
  1918.          * 生成query params
  1919.          * @param array $array 关联数组
  1920.          * @author xiaobing.meng@alibaba-inc.com
  1921.          * @since 2012-03-04
  1922.          * @return string 返回诸如 key1=value1&key2=value2
  1923.          */
  1924.         public function to_query_string($options = array()){
  1925.                 $temp = array();
  1926.                
  1927.                 foreach ($options as $key => $value){
  1928.                         if (is_string($key) && !is_array($value)){
  1929.                                 $temp[] = rawurlencode($key) . '=' . rawurlencode($value);
  1930.                         }
  1931.                 }
  1932.  
  1933.                 return implode('&', $temp);
  1934.         }
  1935.        
  1936.         /**
  1937.          * 转化十六进制的数据为base64
  1938.          *
  1939.          * @param string $str (Required) 要转化的字符串
  1940.          * @author xiaobing.meng@alibaba-inc.com
  1941.          * @since 2012-03-20
  1942.          * @return string Base64-encoded string.
  1943.          */
  1944.         private function hex_to_base64($str){
  1945.                 $result = '';
  1946.  
  1947.                 for ($i = 0; $i < strlen($str); $i += 2){
  1948.                         $result .= chr(hexdec(substr($str, $i, 2)));
  1949.                 }
  1950.  
  1951.                 return base64_encode($result);
  1952.         }
  1953.  
  1954.         private function s_replace($subject){
  1955.                 $search = array('<','>','&','\'','"');
  1956.                 $replace = array('&lt;','&gt;','&amp;','&apos;','&quot;');
  1957.                 return str_replace($search, $replace, $subject);
  1958.         }
  1959.        
  1960.         /**
  1961.          * 检测是否含有中文
  1962.          * @param string $subject
  1963.          * @author xiaobing.meng@alibaba-inc.com
  1964.          * @since 2012-06-06
  1965.          * @return boolean
  1966.          */
  1967.         private function chk_chinese($str){
  1968.                 return preg_match('/[\x80-\xff]./', $str);
  1969.         }
  1970.        
  1971.         /**
  1972.          * 检测是否GB2312编码
  1973.          * @param string $str
  1974.          * @author xiaobing.meng@alibaba-inc.com
  1975.          * @since 2012-03-20
  1976.          * @return boolean false UTF-8编码  TRUE GB2312编码
  1977.          */
  1978.         function is_gb2312($str)  {  
  1979.             for($i=0; $i<strlen($str); $i++) {  
  1980.                 $v = ord( $str[$i] );  
  1981.                 if( $v > 127) {  
  1982.                     if( ($v >= 228) && ($v <= 233) ){  
  1983.                         if( ($i+2) >= (strlen($str) - 1)) return true;  // not enough characters  
  1984.                         $v1 = ord( $str[$i+1] );  
  1985.                         $v2 = ord( $str[$i+2] );  
  1986.                         if( ($v1 >= 128) && ($v1 <=191) && ($v2 >=128) && ($v2 <= 191) )  
  1987.                             return false;   //UTF-8编码  
  1988.                         else  
  1989.                             return true;    //GB编码  
  1990.                     }  
  1991.                 }  
  1992.             }  
  1993.         }
  1994.  
  1995.  
  1996.         /**
  1997.          * 检测是否GBK编码
  1998.          * @param string $str
  1999.          * @param boolean $gbk
  2000.          * @author xiaobing.meng@alibaba-inc.com
  2001.          * @since 2012-06-04
  2002.          * @return boolean
  2003.          */    
  2004.         private function check_char($str,$gbk = true){
  2005.             for($i=0; $i<strlen($str); $i++) {
  2006.                 $v = ord( $str[$i] );
  2007.                 if( $v > 127){
  2008.                     if( ($v >= 228) && ($v <= 233) ){
  2009.                          if(($i+2)>= (strlen($str)-1)) return $gbk?true:FALSE;  // not enough characters
  2010.                          $v1 = ord( $str[$i+1] ); $v2 = ord( $str[$i+2] );
  2011.                          if($gbk){
  2012.                               return (($v1 >= 128) && ($v1 <=191) && ($v2 >=128) && ($v2 <= 191))?FALSE:TRUE;//GBK
  2013.                          }else{
  2014.                               return (($v1 >= 128) && ($v1 <=191) && ($v2 >=128) && ($v2 <= 191))?TRUE:FALSE;
  2015.                          }
  2016.                     }
  2017.                 }
  2018.             }
  2019.            return $gbk?TRUE:FALSE;
  2020.         }
  2021.  
  2022.  
  2023.         /**
  2024.          * 读取目录
  2025.          * @param string $dir (Required) 目录名
  2026.          * @param boolean $recursive (Optional) 是否递归,默认为false
  2027.          * @author xiaobing.meng@alibaba-inc.com
  2028.          * @since 2012-03-05
  2029.          * @return array
  2030.          */
  2031.         private  function read_dir($dir,$exclude = ".|..|.svn",$recursive = false){
  2032.                 static $file_list_array = array();
  2033.                
  2034.                 $exclude_array = explode("|", $exclude);
  2035.                 //读取目录
  2036.                 if($handle = opendir($dir)){
  2037.                         while ( false !== ($file = readdir($handle))){                                         
  2038.                                 if(!in_array(strtolower($file),$exclude_array)){
  2039.                                         $new_file = $dir.'/'.$file;                                    
  2040.                                         if(is_dir($new_file) && $recursive){
  2041.                                                 $this->read_dir($new_file,$exclude,$recursive);
  2042.                                         }else{
  2043.                                                 $file_list_array[] = array(
  2044.                                                         'path' => $new_file,
  2045.                                                         'file' => $file,
  2046.                                                 );
  2047.                                         }
  2048.                                 }
  2049.                         }
  2050.                        
  2051.                         closedir($handle);                     
  2052.                 }                      
  2053.                
  2054.                 return $file_list_array;
  2055.         }
  2056.        
  2057.        
  2058.         /**
  2059.          * 转化object数组为固定个xml格式
  2060.          * @param string $bucket (Required)
  2061.          * @param array $object_array (Required)
  2062.          * @throws OSS_Exception
  2063.          * @author xiaobing.meng@alibaba-inc.com
  2064.          * @since 2011-12-27
  2065.          * @return string
  2066.          */
  2067.         private function make_object_group_xml($bucket,$object_array){
  2068.                 $xml = '';
  2069.                 $xml .= '<CreateFileGroup>';
  2070.  
  2071.                 if($object_array){
  2072.                         if(count($object_array) > self::OSS_MAX_OBJECT_GROUP_VALUE){
  2073.                                 throw new OSS_Exception(OSS_OBJECT_GROUP_TOO_MANY_OBJECT, '-401');
  2074.                         }
  2075.                         $index = 1;
  2076.                         foreach ($object_array as $key=>$value){
  2077.                                 $object_meta = (array)$this->get_object_meta($bucket, $value);
  2078.                                 if(isset($object_meta) && isset($object_meta['status']) && isset($object_meta['header']) && isset($object_meta['header']['etag']) && $object_meta['status'] == 200){
  2079.                                         $xml .= '<Part>';
  2080.                                         $xml .= '<PartNumber>'.intval($index).'</PartNumber>';
  2081.                                         $xml .= '<PartName>'.$value.'</PartName>';
  2082.                                         $xml .= '<ETag>'.$object_meta['header']['etag'].'</ETag>';
  2083.                                         $xml .= '</Part>';
  2084.  
  2085.                                         $index++;
  2086.                                 }
  2087.                         }
  2088.                 }else{
  2089.                         throw new OSS_Exception(OSS_OBJECT_ARRAY_IS_EMPTY, '-400');
  2090.                 }
  2091.  
  2092.                 $xml .= '</CreateFileGroup>';
  2093.  
  2094.                 return $xml;
  2095.         }
  2096.  
  2097.         /**
  2098.          * 检验bucket名称是否合法
  2099.          * bucket的命名规范:
  2100.          * 1. 只能包括小写字母,数字,下划线(_)和短横线(-)
  2101.          * 2. 必须以小写字母或者数字开头
  2102.          * 3. 长度必须在3-255字节之间
  2103.          * @param string $bucket (Required)
  2104.          * @author xiaobing.meng@alibaba-inc.com
  2105.          * @since 2011-12-27
  2106.          * @return boolean
  2107.          */
  2108.         private function validate_bucket($bucket){
  2109.                 $pattern = '/^[a-z0-9][a-z0-9_\\-]{2,254}$/';
  2110.                 if (! preg_match ( $pattern, $bucket )) {
  2111.                         return false;
  2112.                 }
  2113.                 return true;
  2114.         }
  2115.  
  2116.         /**
  2117.          * 检验object名称是否合法
  2118.          * object命名规范:
  2119.          * 1. 规则长度必须在1-1023字节之间
  2120.          * 2. 使用UTF-8编码
  2121.          * @param string $object (Required)
  2122.          * @author xiaobing.meng@alibaba-inc.com
  2123.          * @since 2011-12-27
  2124.          * @return boolean
  2125.          */
  2126.         private function validate_object($object){
  2127.                 $pattern = '/^.{1,1023}$/';
  2128.                 if (empty ( $object ) || ! preg_match ( $pattern, $object )) {
  2129.                         return false;
  2130.                 }
  2131.                 return true;
  2132.         }
  2133.  
  2134.         /**
  2135.          * 检验$options
  2136.          * @param array $options (Optional)
  2137.          * @throws OSS_Exception
  2138.          * @author xiaobing.meng@alibaba-inc.com
  2139.          * @since 2011-12-27
  2140.          * @return boolean
  2141.          */
  2142.         private function validate_options($options){
  2143.                 //$options
  2144.                 if ($options != NULL && ! is_array ( $options )) {
  2145.                         throw new OSS_Exception ($options.':'.OSS_OPTIONS_MUST_BE_ARRAY);
  2146.                 }
  2147.         }
  2148.  
  2149.         /**
  2150.          * 检测上传文件的内容
  2151.          * @param array $options (Optional)
  2152.          * @throws OSS_Exception
  2153.          * @author xiaobing.meng@alibaba-inc.com
  2154.          * @since  2011-12-27
  2155.          * @return string
  2156.          */
  2157.         private function validate_content($options){
  2158.                 if(isset($options[self::OSS_CONTENT])){
  2159.                         if($options[self::OSS_CONTENT] == '' || !is_string($options[self::OSS_CONTENT])){
  2160.                                 throw new OSS_Exception(OSS_INVALID_HTTP_BODY_CONTENT,'-600');
  2161.                         }
  2162.                 }else{
  2163.                         throw new OSS_Exception(OSS_NOT_SET_HTTP_CONTENT, '-601');
  2164.                 }
  2165.         }
  2166.  
  2167.         /**
  2168.          * 验证文件长度
  2169.          * @param array $options (Optional)
  2170.          * @author xiaobing.meng@alibaba-inc.com
  2171.          * @since 2011-12-27
  2172.          * @return void
  2173.          */
  2174.         private function validate_content_length($options){
  2175.                 if(isset($options[self::OSS_LENGTH]) && is_numeric($options[self::OSS_LENGTH])){
  2176.                         if( ! $options[self::OSS_LENGTH] > 0){
  2177.                                 throw new OSS_Exception(OSS_CONTENT_LENGTH_MUST_MORE_THAN_ZERO, '-602');
  2178.                         }
  2179.                 }else{
  2180.                         throw new OSS_Exception(OSS_INVALID_CONTENT_LENGTH, '-602');
  2181.                 }
  2182.         }
  2183.  
  2184.         /**
  2185.          * 校验BUCKET/OBJECT/OBJECT GROUP是否为空
  2186.          * @param  string $name (Required)
  2187.          * @param  string $errMsg (Required)
  2188.          * @throws OSS_Exception
  2189.          * @author xiaobing.meng@alibaba-inc.com
  2190.          * @since 2011-12-27
  2191.          * @return void
  2192.          */
  2193.         private function is_empty($name,$errMsg){
  2194.                 if(empty($name)){
  2195.                         throw new OSS_Exception($errMsg);
  2196.                 }
  2197.         }
  2198.  
  2199.         /**
  2200.          * 设置http header
  2201.          * @param string $key (Required)
  2202.          * @param string $value (Required)
  2203.          * @param array $options (Required)
  2204.          * @throws OSS_Exception
  2205.          * @author xiaobing.meng@alibaba-inc.com
  2206.          * @return void
  2207.          */
  2208.         private static function set_options_header($key, $value, &$options) {
  2209.                 if (isset ( $options [self::OSS_HEADERS] )) {
  2210.                         if (! is_array ( $options [self::OSS_HEADERS] )) {
  2211.                                 throw new OSS_Exception(OSS_INVALID_OPTION_HEADERS, '-600');
  2212.                         }
  2213.                 } else {
  2214.                         $options [self::OSS_HEADERS] = array ();
  2215.                 }
  2216.  
  2217.                 $options [self::OSS_HEADERS] [$key] = $value;
  2218.         }      
  2219. }
  2220.  
downloadsdk.class.php Source code - Download Ali cloud storage v1.1 PHP file upload system root directory Source code
Related Source Codes/Software:
Qr code generation V1.1 online - Directions for use: 2016-10-23
Short url program V1.2 (with black and white list function) - This short url program has three features: 2016-10-22
V2.0 Openbiz Cubi PHP rapid development platform - Openbiz Cubi is a PHP-based open source rapid appl... 2016-10-22
At half past eight self-help chain utf-8 v1.0 - Installation instructions After downloading befor... 2016-10-22
New Yorker rat taobao station group management system v2.0 - Rats off Amoy Taobao station management system 2.0... 2016-10-22
Desert arashi v0.1.2 file operations procedures - Desert arashi file operations procedures is a simp... 2016-10-23
Good business mall v2.0 open source edition - Good business, open source shopping mall, which is... 2016-10-23
Easy website system v2.0 - Business easy built station system (Sunnyi Website... 2016-10-23
Emlog for SAE v4.2.1 - Emlog for SAE is suitable for SAE emlog used modif... 2016-10-23
Food science and technology chain edition v1.1 online reservation system - Treat chain version of the main functions of the o... 2016-10-23
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top