我需要发送一个cURL请求,其中包含一个要上传的文件以及一个JSON字符串。当发送JSON时,我可以得到一个正确格式化的请求,但文件将其丢弃。
$postData = array(
'JSON'=> json_encode($jsonParams),
$reference => '@'.$tmp_file_path
);
//Borrowed function from: http://scraperblog.blogspot.com/2013/07/php-curl-multipart-form-posting.html
function multipart_build($fields, $boundary){
$retval = '';
foreach($fields as $key => $value){
$retval .= "--$boundary'nContent-Disposition: form-data; name='"$key'"'n'n$value'n";
}
$retval .= "--$boundary--";
return $retval;
}
$boundary = "--requestboundary-xxx";
$request = $this->multipart_build($postData,$boundary);
$curl = curl_init();
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // stop verifying certificate
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data; boundary=$boundary"));
curl_setopt($curl, CURLOPT_URL, $target);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
$response = curl_exec($curl);
$info = curl_getinfo($curl);
curl_close($curl);
$引用需要绑定到$jsonParams中的值,以便接收服务器可以确保上传的文件附加到相应的数据字符串包。
////////////////////////////////////////////////////////////
Marc B评论后更新
////////////////////////////////////////////////////////////
所以我的第一个方法不是使用我自己的multipart。我选择multipart的原因是至少我能从服务器得到响应。这是原始代码。
$curl_file_object = curl_file_create($attachmentFile['tmp_name'], $attachmentFile['type'], $reference);
$postData= array(
'JSON'=> json_encode($jsonParams),
$reference => $curl_file_object,
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $target);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // stop verifying certificate
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data;"));
curl_setopt($curl, CURLOPT_POST, true); // enable posting
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); // post data
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); // if any redirection after upload
$response = curl_exec($curl);
$info = curl_getinfo($curl);
curl_close($curl);
debug($info);
我得到:
[url] => --------
[content_type] =>
[http_code] => 0
[header_size] => 0
[request_size] => 0
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.031
[namelookup_time] => 0
[connect_time] => 0.031
[pretransfer_time] => 0
[size_upload] => 0
[size_download] => 0
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 0
[redirect_time] => 0
[redirect_url] =>
[primary_ip] => --------
[certinfo] => Array
(
)
[primary_port] => --------
[local_ip] => --------
[local_port] => --------
我至少得了400分。
不要构建自己的multipart。Curl完全有能力为您做到这一点:
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
它将取一个数组,并自动执行任何需要的操作。
如果你是PHP 5.5+,你也可以使用curlfile作为文件部分,而不需要@
的hack。
使用CURLFile代替curl_file_create()修复了这个问题。尽管它们应该是相同的…