一、CURL通过post发送JSON并接收JSON
CURL请求代码:
//要发送的数据
$data = (
'name' => '张三',
'age' => '32'
);
$header = array(
'Content-Type: application/json; charset=utf-8',
'Content-Length:' . strlen($data))
);
$url = https://www.xxx.com/xxx/xxx/xxx.php
//调用方法,请求数据
$rst = tocurl($url,$header,json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT));
echo $rst;
/**
* CURL 方法
* @param String $url 请求的地址
* @param Array $header 自定义的header数据(请求头)
* @param Array $data POST的数据
* @return String
*/
function tocurl($url, $header, $data){
$ch = curl_init();
if(substr($url,0,5)=='https'){
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true); // 从证书中检查SSL加密算法是否存在
}
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
if($error=curl_error($ch)){
die($error);
}
//通过curl_getinfo()可以得到请求头的状态
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
//这里可以看到结果中header和body信息是在一起的,那么如何分离它们呢。方法有二种,一是通过curl自带的curl_getinfo()方法获取头的长度,然后使用substr来分割字符串。示例代码如下:
// 把body 和 header 分离
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == '200') {
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);
}
//二选一即可。
//第二种方法基于header和body是通过两个回车换行来分割的,所以可以通过如下代码实现:
//$response = curl_exec($ch);
//if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == '200') {
// list($header, $body) = explode(" ", response, 2);
//}
curl_close($ch);
return $response;
}
服务器端获取post数据代码:
//我们通过下面这种方式获取数据,最后获取到的数据是空值。
var_dump($_POST);
//上网搜索了一下发现PHP默认只识别application/x-www.form-urlencoded标准的数据类型,修改头信息也没有结果…只能通过以下方式获得数据
//这两种方式都可以获取到数据(二选一即可)
$post = $GLOBALS['HTTP_RAW_POST_DATA'];
$post2 = file_get_contents("php://input");
二、CURL 请求头和响应头
1.从CURL中获取响应头
$oCurl = curl_init();
// 设置请求头, 有时候需要,有时候不用,看请求网址是否有对应的要求
$header[] = "Content-type: application/x-www-form-urlencoded";
$user_agent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36";
curl_setopt($oCurl, CURLOPT_URL, $sUrl);
curl_setopt($oCurl, CURLOPT_HTTPHEADER,$header);
// 返回 response_header, 该选项非常重要,如果不为 true, 只会获得响应的正文
curl_setopt($oCurl, CURLOPT_HEADER, true);
// 是否不需要响应的正文,为了节省带宽及时间,在只需要响应头的情况下可以不要正文
curl_setopt($oCurl, CURLOPT_NOBODY, true);
// 使用上面定义的 ua
curl_setopt($oCurl, CURLOPT_USERAGENT,$user_agent);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
// 不用 POST 方式请求, 意思就是通过 GET 请求
curl_setopt($oCurl, CURLOPT_POST, false);
$sContent = curl_exec($oCurl);
// 获得响应结果里的:头大小
$headerSize = curl_getinfo($oCurl, CURLINFO_HEADER_SIZE);
// 根据头大小去获取头信息内容
$header = substr($sContent, 0, $headerSize);
curl_close($oCurl);
2.从curl中获取请求头
$oCurl = curl_init();
curl_setopt($oCurl, CURLOPT_URL, "https://117.28.240.235:8002/ipcc/agent/login");
curl_setopt($oCurl, CURLOPT_HTTPHEADER, $header);
//关闭https验证
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
//至关重要,CURLINFO_HEADER_OUT选项可以拿到请求头信息
curl_setopt($oCurl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($oCurl, CURLOPT_POST, 1);
curl_setopt($oCurl, CURLOPT_POSTFIELDS, $bodystr);
$sContent = curl_exec($oCurl);
//通过curl_getinfo()可以得到请求头的信息
$a=curl_getinfo($oCurl);
相关知识
一、JSON与Array之间转换汉字问题
Array转JSON 问题:
$array = [
'name' => '张三',
'age' => 21
];
echo json_encode($array);
/*
* 结果:
* {"name":"u5f20u4e09","age":21}
*/
echo json_encode($array,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
/*
* 结果:
* { "name": "张三", "age": 21 }
*/
JSON转换Array如果遇到汉字问题,则需要下面这种方式来处理:
echo json_decode(trim($post,chr(239).chr(187).chr(191)),TRUE);
二、对数组排序(属性名字母顺序排序) 小技巧
public function argSort($para)
{
ksort($para);
reset($para);
return $para;
}
三、数组转换为string
/**
* 将数组转换为string
*
* @param $para 数组
* @param $sort 是否需要排序
* @param $encode 是否需要URL编码
* @return string
*/
public function createLinkString($para, $sort, $encode)
{
if ($para == null || !is_array($para)) {
return "";
}
$linkString = "";
if ($sort) {
$para = argSort($para);
}
while (list($key, $value) = each($para)) {
if ($encode) {
$value = urlencode($value);
}
$linkString .= $key . "=" . $value . "&";
}
// 去掉最后一个&字符
$linkString = substr($linkString, 0, count($linkString) - 2);
return $linkString;
}
四、CURL抓取数据
PHP的curl功能十分强大,简单点说,就是一个PHP实现浏览器的基础。
最常用的可能就是抓取远程数据或者向远程POST数据。但是在这个过程中,调试时,可能会有查看header的必要。
echo get('http://www.baidu.com');exit;
function get($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //TRUE 将curl_exec()获取的信息以字符串返回,而不是直接输出。
$header = ['User-Agent: php test']; //设置一个你的浏览器agent的header
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_HEADER, 1); //返回response头部信息
curl_setopt($ch, CURLINFO_HEADER_OUT, true); //TRUE 时追踪句柄的请求字符串,从 PHP 5.1.3 开始可用。这个很关键,就是允许你查看请求header
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HEADER_OUT); //官方文档描述是“发送请求的字符串”,其实就是请求的header。这个就是直接查看请求header,因为上面允许查看
curl_close($ch);
return $result;
}
结果如下,很清楚的让你知道在请求URL的过程中,发送的header和返回的header信息:
GET / HTTP/1.1
Host: www.baidu.com
Accept: */*
User-Agent: php test
HTTP/1.1 200 OK
Server: bfe/1.0.8.18
Date: Tue, 04 Jul 2017 01:25:19 GMT
Content-Type: text/html
Content-Length: 2381
Last-Modified: Mon, 23 Jan 2017 13:27:32 GMT
Connection: Keep-Alive
ETag: "588604c4-94d"
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Pragma: no-cache
Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
Accept-Ranges: bytes
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8>