服务端常见的post提交有三种方式,这里主要记录curl方式
1、服务端进行http-post的三种方法
1.1 通过curl函数
function post($url, $post_data = '', $timeout = 5){//curl
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_POST, 1);
if($post_data != ''){
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_HEADER, false);
$file_contents = curl_exec($ch);
curl_close($ch);
return $file_contents;
}
1.2 通过Filesystem函数
function post2($url, $data)
{
$postdata = http_build_query(
$data
);
$opts = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
),
);
$context = stream_context_create($opts);
$result = file_get_contents($url, false, $context);
return $result;
}
1.3 借助网络函数
fsockopen();
fwrite();
fread();
fclose();
以上三种方法源码参考自:原文
2、我本地构造的curl成功提交post
2.1 curl提交post源码
/**
* [sendPostHttp]
* @param string $url 提交地址,[schema://host:port]
* @param array $params 需要通过post提交的数据
* @param integer $timeout 连接超时
* @return mixed 提交状态
*/
static public function sendPostHttp($url, $params, $timeout = 5)
{
// 构造post提交
$ch = curl_init();
$option = array(
CURLOPT_URL => $url,
CURLOPT_CONNECTTIMEOUT => $timeout,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_HEADER => false,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($params),
CURLOPT_RETURNTRANSFER => true,
);
curl_setopt_array($ch, $option);
// 提交post
$ret = curl_exec($ch);
if (false == $ret) {
echo curl_error($ch);
}
curl_close($ch);
return $ret;
}
2.2 构造请求中遇到的坑
1、构造过程中参考了php手册中的curl_setopt
所以首次尝试时,CURLOPT_POSTFIELDS的值用了数组:
CURLOPT_POSTFIELDS => $params
结果总是返回错误信息:
Recv failure: Connection was reset
2、为什么会出现这样的错误呢?
我们注意到CURLOPT_POSTFIELDS说明中如果value是数组,
Content-Type头将会被设置成multipart/form-data
猜测原因就出在CURLOPT_POSTFIELDS的值上边,所以将其传值改为CURLOPT_POSTFIELDS => http_build_query($params),果然success!
参考:http_build_query构造请求字符串
2.3 未解的疑问
但是,为什么CURLOPT_POSTFIELDS会产生这样影响呢?查了一下multipart/form-data,但是没有得到具体原因。参见multipart/form-data请求分析
推测可能是对方服务器不接受这样的Content-Type吧?
或者对multipart/form-data的不兼容?