设为首页 收藏本站
查看: 459|回复: 0

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

[复制链接]

尚未签到

发表于 2017-4-10 09:51:30 | 显示全部楼层 |阅读模式
  由于php的curl在curl_setopt($curl, CURLOPT_POSTFIELDS, xxx)时, 当xxx为数组时, 如果值的第一个字符是@, 则认为是文件上传, 当同时需要上传文件, 也需要提交可能首字符为@的其他普通数据时, 存在冲突. 因此, 在api_common.php中的post数据的设置进行了封装
  

  

<?php
/**
* php-curl库封装
* author: selfimpr
* blog: http://blog.csdn.net/lgg201
* mail: lgg860911@yahoo.com.cn
*/
define('API_CURL_UPLOAD_FILE','__file');
#支持的请求方法
define('REQUEST_METHOD_GET','GET');
define('REQUEST_METHOD_POST','POST');
define('REQUEST_METHOD_HEAD','HEAD');
#请求行为
define('REQUEST_BEHAVIOR_ALLOW_REDIRECT','allow_redirect');
define('REQUEST_BEHAVIOR_MAX_REDIRECT','max_redirect');
define('REQUEST_BEHAVIOR_USER_AGENT','user_agent');
define('REQUEST_BEHAVIOR_AUTOREFERER','autoreferer');
define('REQUEST_BEHAVIOR_UPLOAD','upload');
define('REQUEST_BEHAVIOR_CONNECTTIMEOUT','connecttimeout');
define('REQUEST_BEHAVIOR_DNS_CACHE_TIMEOUT','dns_cache_timeout');
define('REQUEST_BEHAVIOR_TIMEOUT','timeout');
define('REQUEST_BEHAVIOR_ENCODING','encoding');
define('REQUEST_BEHAVIOR_ERROR_HANDLER','error_handler');
define('REQUEST_BEHAVIORS','behaviors');
$GLOBALS[REQUEST_BEHAVIORS]= array(
REQUEST_BEHAVIOR_ALLOW_REDIRECT=> TRUE,
REQUEST_BEHAVIOR_MAX_REDIRECT=> 5,
REQUEST_BEHAVIOR_USER_AGENT=> 'curl-lib',
REQUEST_BEHAVIOR_AUTOREFERER=> TRUE,
REQUEST_BEHAVIOR_UPLOAD=> FALSE,
REQUEST_BEHAVIOR_CONNECTTIMEOUT=> 3,
REQUEST_BEHAVIOR_DNS_CACHE_TIMEOUT=> 3600,
REQUEST_BEHAVIOR_TIMEOUT=> 3,
REQUEST_BEHAVIOR_ENCODING=> 'gzip',
REQUEST_BEHAVIOR_ERROR_HANDLER=> '__default_curl_error_handler',
);
define('MULTIPART_FORM_DATA_HEAD_FMT','Content-Type: multipart/form-data; boundary=----------------------------%s');
define('MULTIPART_FORM_DATA_BODY_STRING',"------------------------------%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n");
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");
define('MULTIPART_FORM_DATA_BODY_END',"------------------------------%s--\r\n\r\n");
#响应键值
define('RESP_CODE','resp_code');
define('RESP_BODY','resp_body');
define('RESP_HEADER','resp_header');
#HTTP 1xx状态验证
define('HTTP_1XX_RESP','/^HTTP\/1.[01] 1\d{2} \w+/');
#默认错误处理的错误消息
define('E_CURL_ERROR_FMT','curl "%s" error[%d]: %s');
#默认的curl错误处理
function __default_curl_error_handler($curl, $url, $errno, $errstr) {
trigger_error(sprintf(E_CURL_ERROR_FMT, $url, $errno, $errstr), E_USER_ERROR);
}
#切换CURL请求方法
function __method_switch($curl, $method) {
switch ( $method) {
case REQUEST_METHOD_POST:
__curl_setopt($curl, CURLOPT_POST, TRUE);
break;
case REQUEST_METHOD_HEAD:
__curl_setopt($curl, CURLOPT_NOBODY, TRUE);
break;
case REQUEST_METHOD_GET:
__curl_setopt($curl, CURLOPT_HTTPGET, TRUE);
break;
default:
break;
}
}
#设置默认头信息
function __default_header_set($curl) {
__curl_setopt($curl, CURLOPT_RETURNTRANSFER,TRUE);
__curl_setopt($curl, CURLOPT_HEADER,TRUE);
__curl_setopt($curl, CURLOPT_FOLLOWLOCATION,(bool)curl_behavior(REQUEST_BEHAVIOR_ALLOW_REDIRECT));
__curl_setopt($curl, CURLOPT_MAXREDIRS,(int)curl_behavior(REQUEST_BEHAVIOR_MAX_REDIRECT));
__curl_setopt($curl, CURLOPT_USERAGENT,(string)curl_behavior(REQUEST_BEHAVIOR_USER_AGENT));
__curl_setopt($curl, CURLOPT_AUTOREFERER,(bool)curl_behavior(REQUEST_BEHAVIOR_AUTOREFERER));
__curl_setopt($curl, CURLOPT_UPLOAD,(bool)curl_behavior(REQUEST_BEHAVIOR_UPLOAD));
__curl_setopt($curl, CURLOPT_CONNECTTIMEOUT,(int)curl_behavior(REQUEST_BEHAVIOR_CONNECTTIMEOUT));
__curl_setopt($curl, CURLOPT_DNS_CACHE_TIMEOUT,(int)curl_behavior(REQUEST_BEHAVIOR_DNS_CACHE_TIMEOUT));
__curl_setopt($curl, CURLOPT_TIMEOUT,(int)curl_behavior(REQUEST_BEHAVIOR_TIMEOUT));
__curl_setopt($curl, CURLOPT_ENCODING,(string)curl_behavior(REQUEST_BEHAVIOR_ENCODING));
}
#设置用户自定义头信息
function __custom_header_set($curl, $headers = NULL) {
if ( empty($headers) ) return ;
if ( is_string($headers) )
$headers= explode("\r\n", $headers);
#类型修复
foreach ( $headers as &$header )
if ( is_array($header) )
$header= sprintf('%s: %s', $header[0], $header[1]);
__curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
}
#设置请求body
function __datas_set($curl, $datas = NULL) {
if ( empty($datas) ) return ;
if ( is_array($datas) ) {
$custom_body= FALSE;
$uniqid= uniqid();
$custom_body_str= '';
foreach ( $datas as $name => $data ) {
if ( is_array($data) && array_key_exists(API_CURL_UPLOAD_FILE, $data) ) {
$file= $data[API_CURL_UPLOAD_FILE];
if ( file_exists($file) ) {
$custom_body= TRUE;
$custom_body_str.= sprintf(MULTIPART_FORM_DATA_BODY_FILE,
$uniqid, $name,
$file, file_get_contents($file));
}
} else {
$custom_body_str.= sprintf(MULTIPART_FORM_DATA_BODY_STRING,
$uniqid, $name, $data);
}
}
if ( $custom_body ) {
curl_setopt($curl, CURLOPT_HTTPHEADER, array(sprintf(MULTIPART_FORM_DATA_HEAD_FMT, $uniqid)));
$datas= $custom_body_str . sprintf(MULTIPART_FORM_DATA_BODY_END, $uniqid);
}
}
__curl_setopt($curl, CURLOPT_POSTFIELDS, $datas);
}
#对curl_setopt的封装
function __curl_setopt($curl, $optname, $optval) {
curl_setopt($curl, $optname, $optval);
__curl_error($curl);
}
#curl错误检查处理
function __curl_error($curl) {
if ( curl_errno($curl) ) {
$url= curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);
$errno= curl_errno($curl);
$errstr= curl_error($curl);
$errh= curl_behavior(REQUEST_BEHAVIOR_ERROR_HANDLER);
if ( function_exists($errh) )
$errh($curl, $url, $errno, $errstr);
}
}
#api默认行为切换
function curl_behavior($names, $values = NULL) {
if ( !is_string($names) && !is_array($names) ) return ;
if ( !is_null($values) ) {
if ( is_string($names) )
$GLOBALS[REQUEST_BEHAVIORS][$names]= $values;
else if ( is_array($names) && !is_array($values) )
foreach ( $names as $name )
$GLOBALS[REQUEST_BEHAVIORS][$name]= $values;
else if ( is_array($names) && is_array($values) )
foreach ( $names as $k => $name )
$GLOBALS[REQUEST_BEHAVIORS][$name]= $values[$k];
}
if ( is_string($names) ) {
$return= $GLOBALS[REQUEST_BEHAVIORS][$names];
} else if ( is_array($names) ) {
$return= array();
foreach ( $names as $name )
$return[$name]= array_key_exists($name, $GLOBALS[REQUEST_BEHAVIORS])
? $GLOBALS[REQUEST_BEHAVIORS][$name]
: NULL;
}
return $return;
}
#请求入口
function curl_request($url, $method, $datas = NULL, $headers = NULL) {
$curl= curl_init($url);
__method_switch($curl, $method);
__default_header_set($curl);
__custom_header_set($curl, $headers);
__datas_set($curl, $datas);
$response= curl_exec($curl);
__curl_error($curl);
$status_code= curl_getinfo($curl, CURLINFO_HTTP_CODE);
$components= explode("\r\n\r\n", $response);
$i= -1;
while ( ++ $i < count($components) )
if ( !preg_match(HTTP_1XX_RESP, $components[$i]) ) break;
$headers= $components[$i];
$body= implode("\r\n\r\n", array_slice($components, $i + 1));
return array(
RESP_CODE=> $status_code,
RESP_HEADER=> $headers,
RESP_BODY=> $body,
);
}
#GET请求
function curl_get($url, $headers = NULL) {
return curl_request($url, REQUEST_METHOD_GET, NULL, $headers);
}
#POST请求
function curl_post($url, $datas = NULL, $headers = NULL) {
return curl_request($url, REQUEST_METHOD_POST, $datas, $headers);
}
#HEAD请求
function curl_head($url, $headers = NULL) {
return curl_request($url, REQUEST_METHOD_HEAD, NULL, $headers);
}
#构造上传文件字段
function curl_post_file($file) {
return array(
API_CURL_UPLOAD_FILE=> $file,
);
}
#读取响应码
function curl_resp_code($resp) {
return $resp[RESP_CODE];
}
#读取响应头
function curl_resp_header($resp) {
return $resp[RESP_HEADER];
}
#读取响应体
function curl_resp_body($resp) {
return $resp[RESP_BODY];
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-362745-1-1.html 上篇帖子: php中的冒泡排序,选择排序,插入排序 下篇帖子: 关于PHP的工作流引擎EZER简介
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表