注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

phperwuhan的博客

记载一个phper的历程!phperwuhan.blog.163.com

 
 
 

日志

 
 

php-curl封装[避免上传文件二义性Bug]  

2013-03-31 11:23:39|  分类: php |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
来源:http://blog.csdn.net/lgg201/article/details/8000756

由 于php的curl在curl_setopt($curl, CURLOPT_POSTFIELDS, xxx)时, 当xxx为数组时, 如果值的第一个字符是@, 则认为是文件上传, 当同时需要上传文件, 也需要提交可能首字符为@的其他普通数据时, 存在冲突. 因此, 在api_common.php中的post数据的设置进行了封装


  1. <?php  
  2. /** 
  3.  * php-curl库封装 
  4.  * author: selfimpr 
  5.  * blog: http://blog.csdn.net/lgg201 
  6.  * mail: lgg860911@yahoo.com.cn 
  7.  */  
  8.   
  9. define('API_CURL_UPLOAD_FILE',                          '__file');  
  10.   
  11. #支持的请求方法  
  12. define('REQUEST_METHOD_GET',                            'GET');  
  13. define('REQUEST_METHOD_POST',                           'POST');  
  14. define('REQUEST_METHOD_HEAD',                           'HEAD');  
  15.   
  16. #请求行为  
  17. define('REQUEST_BEHAVIOR_ALLOW_REDIRECT',               'allow_redirect');  
  18. define('REQUEST_BEHAVIOR_MAX_REDIRECT',                 'max_redirect');  
  19. define('REQUEST_BEHAVIOR_USER_AGENT',                   'user_agent');  
  20. define('REQUEST_BEHAVIOR_AUTOREFERER',                  'autoreferer');  
  21. define('REQUEST_BEHAVIOR_UPLOAD',                       'upload');  
  22. define('REQUEST_BEHAVIOR_CONNECTTIMEOUT',               'connecttimeout');  
  23. define('REQUEST_BEHAVIOR_DNS_CACHE_TIMEOUT',            'dns_cache_timeout');  
  24. define('REQUEST_BEHAVIOR_TIMEOUT',                      'timeout');  
  25. define('REQUEST_BEHAVIOR_ENCODING',                     'encoding');  
  26. define('REQUEST_BEHAVIOR_ERROR_HANDLER',                'error_handler');  
  27. define('REQUEST_BEHAVIORS',                             'behaviors');  
  28. $GLOBALS[REQUEST_BEHAVIORS] = array(  
  29.     REQUEST_BEHAVIOR_ALLOW_REDIRECT             => TRUE,   
  30.     REQUEST_BEHAVIOR_MAX_REDIRECT               => 5,   
  31.     REQUEST_BEHAVIOR_USER_AGENT                 => 'curl-lib',   
  32.     REQUEST_BEHAVIOR_AUTOREFERER                => TRUE,   
  33.     REQUEST_BEHAVIOR_UPLOAD                     => FALSE,   
  34.     REQUEST_BEHAVIOR_CONNECTTIMEOUT             => 3,   
  35.     REQUEST_BEHAVIOR_DNS_CACHE_TIMEOUT          => 3600,   
  36.     REQUEST_BEHAVIOR_TIMEOUT                    => 3,   
  37.     REQUEST_BEHAVIOR_ENCODING                   => 'gzip',   
  38.     REQUEST_BEHAVIOR_ERROR_HANDLER              => '__default_curl_error_handler',   
  39. );  
  40.   
  41. define('MULTIPART_FORM_DATA_HEAD_FMT',              'Content-Type: multipart/form-data; boundary=----------------------------%s');  
  42. define('MULTIPART_FORM_DATA_BODY_STRING',           "------------------------------%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n");  
  43. define('MULTIPART_FORM_DATA_BODY_FILE',             "------------------------------%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: application/octet-stream\r\n\r\n%s\r\n");  
  44. define('MULTIPART_FORM_DATA_BODY_END',              "------------------------------%s--\r\n\r\n");  
  45.   
  46. #响应键值  
  47. define('RESP_CODE',                                 'resp_code');  
  48. define('RESP_BODY',                                 'resp_body');  
  49. define('RESP_HEADER',                               'resp_header');  
  50.   
  51. #HTTP 1xx状态验证  
  52. define('HTTP_1XX_RESP',                             '/^HTTP\/1.[01] 1\d{2} \w+/');  
  53.   
  54. #默认错误处理的错误消息  
  55. define('E_CURL_ERROR_FMT',                              'curl "%s" error[%d]: %s');  
  56.   
  57. #默认的curl错误处理  
  58. function __default_curl_error_handler($curl$url$errno$errstr) {  
  59.     trigger_error(sprintf(E_CURL_ERROR_FMT, $url$errno$errstr), E_USER_ERROR);  
  60. }  
  61. #切换CURL请求方法  
  62. function __method_switch($curl$method) {  
  63.     switch ( $method) {  
  64.         case REQUEST_METHOD_POST:  
  65.             __curl_setopt($curl, CURLOPT_POST, TRUE);  
  66.             break;  
  67.         case REQUEST_METHOD_HEAD:  
  68.             __curl_setopt($curl, CURLOPT_NOBODY, TRUE);  
  69.             break;  
  70.         case REQUEST_METHOD_GET:  
  71.             __curl_setopt($curl, CURLOPT_HTTPGET, TRUE);  
  72.             break;  
  73.         default:  
  74.             break;  
  75.     }  
  76. }  
  77. #设置默认头信息  
  78. function __default_header_set($curl) {  
  79.     __curl_setopt($curl, CURLOPT_RETURNTRANSFER,            TRUE);  
  80.     __curl_setopt($curl, CURLOPT_HEADER,                    TRUE);  
  81.     __curl_setopt($curl, CURLOPT_FOLLOWLOCATION,            (bool)curl_behavior(REQUEST_BEHAVIOR_ALLOW_REDIRECT));  
  82.     __curl_setopt($curl, CURLOPT_MAXREDIRS,                 (int)curl_behavior(REQUEST_BEHAVIOR_MAX_REDIRECT));  
  83.     __curl_setopt($curl, CURLOPT_USERAGENT,                 (string)curl_behavior(REQUEST_BEHAVIOR_USER_AGENT));  
  84.     __curl_setopt($curl, CURLOPT_AUTOREFERER,               (bool)curl_behavior(REQUEST_BEHAVIOR_AUTOREFERER));  
  85.     __curl_setopt($curl, CURLOPT_UPLOAD,                    (bool)curl_behavior(REQUEST_BEHAVIOR_UPLOAD));  
  86.     __curl_setopt($curl, CURLOPT_CONNECTTIMEOUT,            (int)curl_behavior(REQUEST_BEHAVIOR_CONNECTTIMEOUT));  
  87.     __curl_setopt($curl, CURLOPT_DNS_CACHE_TIMEOUT,         (int)curl_behavior(REQUEST_BEHAVIOR_DNS_CACHE_TIMEOUT));  
  88.     __curl_setopt($curl, CURLOPT_TIMEOUT,                   (int)curl_behavior(REQUEST_BEHAVIOR_TIMEOUT));  
  89.     __curl_setopt($curl, CURLOPT_ENCODING,                  (string)curl_behavior(REQUEST_BEHAVIOR_ENCODING));  
  90. }  
  91. #设置用户自定义头信息  
  92. function __custom_header_set($curl$headers = NULL) {  
  93.     if ( emptyempty($headers) ) return ;  
  94.     if ( is_string($headers) )   
  95.         $headers    = explode("\r\n"$headers);  
  96.     #类型修复  
  97.     foreach ( $headers as &$header )   
  98.         if ( is_array($header) )   
  99.             $header = sprintf('%s: %s'$header[0], $header[1]);  
  100.     __curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);  
  101. }  
  102. #设置请求body  
  103. function __datas_set($curl$datas = NULL) {  
  104.     if ( emptyempty($datas) ) return ;  
  105.     if ( is_array($datas) ) {  
  106.         $custom_body        = FALSE;  
  107.         $uniqid             = uniqid();  
  108.         $custom_body_str    = '';  
  109.         foreach ( $datas as $name => $data ) {  
  110.             if ( is_array($data) && array_key_exists(API_CURL_UPLOAD_FILE, $data) ) {  
  111.                 $file   = $data[API_CURL_UPLOAD_FILE];  
  112.                 if ( file_exists($file) ) {  
  113.                     $custom_body        = TRUE;  
  114.                     $custom_body_str    .= sprintf(MULTIPART_FORM_DATA_BODY_FILE,   
  115.                                         $uniqid$name,   
  116.                                         $filefile_get_contents($file));  
  117.                 }  
  118.             } else {  
  119.                 $custom_body_str        .= sprintf(MULTIPART_FORM_DATA_BODY_STRING,   
  120.                                         $uniqid$name$data);  
  121.             }  
  122.         }  
  123.         if ( $custom_body ) {  
  124.             curl_setopt($curl, CURLOPT_HTTPHEADER, array(sprintf(MULTIPART_FORM_DATA_HEAD_FMT, $uniqid)));  
  125.             $datas              = $custom_body_str . sprintf(MULTIPART_FORM_DATA_BODY_END, $uniqid);  
  126.         }  
  127.     }  
  128.     __curl_setopt($curl, CURLOPT_POSTFIELDS, $datas);  
  129. }  
  130. #对curl_setopt的封装  
  131. function __curl_setopt($curl$optname$optval) {  
  132.     curl_setopt($curl$optname$optval);  
  133.     __curl_error($curl);  
  134. }  
  135. #curl错误检查处理  
  136. function __curl_error($curl) {  
  137.     if ( curl_errno($curl) ) {  
  138.         $url    = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);  
  139.         $errno  = curl_errno($curl);  
  140.         $errstr = curl_error($curl);  
  141.         $errh   = curl_behavior(REQUEST_BEHAVIOR_ERROR_HANDLER);  
  142.         if ( function_exists($errh) )  
  143.             $errh($curl$url$errno$errstr);  
  144.     }  
  145. }  
  146.   
  147. #api默认行为切换  
  148. function curl_behavior($names$values = NULL) {  
  149.     if ( !is_string($names) && !is_array($names) ) return ;  
  150.     if ( !is_null($values) ) {  
  151.         if ( is_string($names) )   
  152.             $GLOBALS[REQUEST_BEHAVIORS][$names] = $values;  
  153.         else if ( is_array($names) && !is_array($values) )  
  154.             foreach ( $names as $name )  
  155.                 $GLOBALS[REQUEST_BEHAVIORS][$name]  = $values;  
  156.         else if ( is_array($names) && is_array($values) )  
  157.             foreach ( $names as $k => $name )   
  158.                 $GLOBALS[REQUEST_BEHAVIORS][$name]  = $values[$k];  
  159.     }  
  160.     if ( is_string($names) ) {  
  161.         $return = $GLOBALS[REQUEST_BEHAVIORS][$names];  
  162.     } else if ( is_array($names) ) {  
  163.         $return = array();  
  164.         foreach ( $names as $name )   
  165.             $return[$name]  = array_key_exists($name$GLOBALS[REQUEST_BEHAVIORS])   
  166.                             ? $GLOBALS[REQUEST_BEHAVIORS][$name]  
  167.                             : NULL;  
  168.     }  
  169.     return $return;  
  170. }  
  171. #请求入口  
  172. function curl_request($url$method$datas = NULL, $headers = NULL) {  
  173.     $curl   = curl_init($url);  
  174.     __method_switch($curl$method);  
  175.     __default_header_set($curl);  
  176.     __custom_header_set($curl$headers);  
  177.     __datas_set($curl$datas);  
  178.     $response   = curl_exec($curl);  
  179.     __curl_error($curl);  
  180.     $status_code    = curl_getinfo($curl, CURLINFO_HTTP_CODE);  
  181.     $components     = explode("\r\n\r\n"$response);  
  182.     $i              = -1;  
  183.     while ( ++ $i < count($components) )   
  184.         if ( !preg_match(HTTP_1XX_RESP, $components[$i]) ) break;  
  185.     $headers        = $components[$i];  
  186.     $body           = implode("\r\n\r\n"array_slice($components$i + 1));  
  187.     return array(  
  188.         RESP_CODE   => $status_code,   
  189.         RESP_HEADER => $headers,   
  190.         RESP_BODY   => $body,   
  191.     );  
  192. }  
  193. #GET请求  
  194. function curl_get($url$headers = NULL) {  
  195.     return curl_request($url, REQUEST_METHOD_GET, NULL, $headers);  
  196. }  
  197. #POST请求  
  198. function curl_post($url$datas = NULL, $headers = NULL) {  
  199.     return curl_request($url, REQUEST_METHOD_POST, $datas$headers);  
  200. }  
  201. #HEAD请求  
  202. function curl_head($url$headers = NULL) {  
  203.     return curl_request($url, REQUEST_METHOD_HEAD, NULL, $headers);  
  204. }  
  205. #构造上传文件字段  
  206. function curl_post_file($file) {  
  207.     return array(  
  208.         API_CURL_UPLOAD_FILE    => $file,   
  209.     );  
  210. }  
  211. #读取响应码  
  212. function curl_resp_code($resp) {  
  213.     return $resp[RESP_CODE];  
  214. }  
  215. #读取响应头  
  216. function curl_resp_header($resp) {  
  217.     return $resp[RESP_HEADER];  
  218. }  
  219. #读取响应体  
  220. function curl_resp_body($resp) {  
  221.     return $resp[RESP_BODY];  

  评论这张
 
阅读(546)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017