QQ推荐的是curl方法,推荐的SDK里用的也是。不过curl是PHP的扩展库,需要另外安装,而调用curl,会牵扯到curl_exec函数,这个函数允许远程执行命令,如果服务器不允许执行curl_exec的话,那么用curl调用QQ的API就是空谈,这时候就需要用到别的方法来实现POST请求。
fsockopen要比curl复杂一点,它是直接用fputs或fwrite写HTTP请求的数据流,而curl已经把所有的内容的封装起来了。
①,第一步是链接到API服务器,值得注意的是,http请求和https请求端口和写法是不一样的。
http的话,是:
$fp = fsockopen('http://'.$host, 80, $errno, $errstr, 20);
https的话,是:
$fp = fsockopen('ssl://'.$host, 443, $errno, $errstr, 20);
$errno如果是0的话,表示请求主机$host失败。
因为要链接的是QQ的API,这里$host是"graph.qq.com", 用第二个HTTPS请求。具体的参照API文档。
②,然后是用fputs写POST请求包。用发送微博add_t请求为例:
$body = http_build_query($params);
$out = "POST /t/add_t HTTP/1.1 \r\n"
."Host: $host\r\n"
."Content-Type: application/x-www-form-urlencoded\r\n"
.'Content-Length: '.strlen($body)."\r\n"
."Connection: close\r\n"
."Cache-Control: no-cache\r\n\r\n";
."$body";
fputs($out);
POST数据包的格式有几点需要注意
- 分行要用"\r\n",而且一定要用双引号。
- body前面的一行,要用两个\r\n
- Content-Length的值一定要包含整个body的长度,$body之后不能再有别的字符串。这个在新浪微博API调用的时候不会有问题,但是QQ的API一定会报错。
- QQ文档里的POST请求示例上有个错误,Connection应该是close,而不是Keep Alive。有兴趣的可以试试Keep Alive,这个值在读取返回值的时候,会让你后悔的。
③,发完数据流,就可以用fgets或fread读取结果了。需要注意的是,fgets是一行一行的读取结果,而fread是按定义的长度读取返回结果。显然,fread要更快一点。
while(!eof($fp)){
$result.= fread($fp, 1024);
}
④,然后就是处理返回结果,返回结果和发出的post数据包是很像的,要的是body部分,所以,直接截取第一个\r\n\r\n之后的数据就对了。