技术饭
curl 发送 form-data 数据流:Content-Type:multipart/form-data; boundary=xxxxxxxxx; charset=utf-8
curl 发送 form-data 数据流:Content-Type:multipart/form-data; boundary=xxxxxxxxx; charset=utf-8,multipart/form-data是基于post方法来传递数据的,并且其请求内容格式为Content-Type: multipart/form-data,用来指定请求内容的数据编码格式。另外,该格式会生成一个boundary字符串来分割请求头与请求体的,具体的是以一个boundary=${boundary}来进行分割。
enctype属性:enctype规定了form表单在发送到服务器时候编码方式,它有如下的三个值:
application/x-www-form-urlencoded:默认的编码方式。但是在用文本的传输和MP3等大型文件的时候,使用这种编码就显得 效率低下
multipart/form-data:指定传输数据为二进制类型,比如图片、mp3、文件
text/plain:纯文体的传输。空格转换为 “+” 加号,但不对特殊字符编码
1)、发送数据格式:
$boundary = "de9bd0ec40af1c325bbb7017481e3173" // 标识符
--{$boundary}
Content-Type:application/octet-stream
Content-Disposition:form-data; name="file"; filename="test.txt"
接口测试!!!
--{$boundary}--
2)、POST数据Header:
"Content-Type:multipart/form-data; boundary=" . $boundary."; charset=utf-8", // form-data 的 boundary 头部
3)、代码实现:
<?php
/**
* 获取curl响应头
* @param $curl
* @param $headerLine
* @return int
*/
function headerHandler($curl, $headerLine):int {
$len = strlen($headerLine);
// HTTP响应头是以:分隔key和value的
$split = explode(':', $headerLine, 2);
if (count($split) > 1) {
$key = trim($split[0]);
$value = trim($split[1]);
// 将响应头的key和value存放在全局变量里
$GLOBALS['G_HEADER'][$key] = $value;
}
return $len;
}
/**
* 处理curl
* @param $url // url地址
* @param $type // GET、POST、PUT、DELETE、PATCH
* @param $data // 发送数据
* @return mixed
*/
function dealCurl($url, $type, mixed $data, $header = []):array {
//设置heder头,如果头部没有Content-Type则默认:content-type: application/json
$existsContentType = false;
foreach ($header as $v) {
if (preg_match('/^(content-type)/', strtolower($v))){
$existsContentType = true;
break;
}
}
if (!$existsContentType) {
array_unshift($header, 'Content-Type:application/json');
$data = json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
}
//初始化curl
$handle = curl_init();
curl_setopt_array(
$handle, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false, //对认证证书来源的检查 https请求 不验证证书和hosts
CURLOPT_SSL_VERIFYHOST => false, //从证书中检查SSL加密算法是否存在
CURLOPT_TIMEOUT => 60,
CURLINFO_HEADER_OUT => 1,
CURLOPT_HEADERFUNCTION => "headerHandler", // 设置header处理函数
CURLOPT_CUSTOMREQUEST => $type,
CURLOPT_HTTPHEADER => $header,
CURLOPT_POSTFIELDS => $data,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_POST => 1
]
);
//执行
$result = curl_exec($handle);
if (curl_errno($handle)) {
return [
"errCode" => 10000,
"errMsg" => "发生错误:" . curl_error($handle),
"result" => [],
"header" => $GLOBALS['G_HEADER']
];
}
//关闭
curl_close($handle);
//返回
$result = is_string($result) && (is_object(json_decode($result)) || is_array(json_decode($result,true))) ? json_decode($result,true) : $result;
return [
"errCode" => 0,
"errMsg" => "操作成功",
"result" => $result,
"header" => $GLOBALS['G_HEADER']
];
}
/**
* 文件上传
* @return void
*/
function fileUpload(){
//文件
$uploadDir = "/ycp/400/"; // 上传目录
$file = "E:\\www\\test\\test.txt";
$fileName = urlencode(basename($file));
$fileContent = file_get_contents($file); // 文件内容
//设置请求body信息,如果是多个文件可以用循环组装
$boundary = md5(uniqid()); // 边界符,可以随机生成
$limiter = "\r\n";
$limiterLine = "--";
$bodyData = $limiterLine . $boundary . $limiter;
$bodyData .= "Content-Type:application/octet-stream" . $limiter;
$bodyData .= "Content-Disposition:form-data; name=\"file\"; filename=\"{$fileName}\"" . $limiter;
$bodyData .= $limiter . $fileContent . $limiter;
$bodyData .= $limiterLine . $boundary . $limiterLine;
//头部
$header = [
"Content-Type:multipart/form-data; boundary=" . $boundary."; charset=utf-8", // form-data 的 boundary 头部
];
//请求
$res = dealCurl(fileUpload, "POST", $bodyData, $header);
if ($res["errCode"] == 0){
//成功
P($res);
} else {
//失败
P($res);
}
}
参考:
multipart/form-data (一种POST 数据提交的方式):https://blog.csdn.net/dreamerrrrrr/article/details/111146763
在php中使用multipart / form-data请求发送文件:https://www.oomake.com/question/5099807
Thinkphp使用curl模拟multipart/form-data表单:https://blog.csdn.net/qq15577969/article/details/126908634
文明上网理性发言!