往后的编章,开始涉及微信公众号的api了,php中访问站点有很多方式,例如file_get_contents也可以get,post站点:
<?php
$formdata = array('sParam1' => 'test1', 'sParam2' => 101, 'isAuto' => 1);
$data = http_build_query($formdata);
$options = array('http' => array('method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => $data));
$context = stream_context_create($options);
$url = 'http://szuzsq.tunnel.qydev.com/weixin/server.php';
$rs = file_get_contents($url, false, $context);
print_r($rs);
?>
但是,最好用也是用得最广的,还是大名鼎鼎的curl.这里对php中的curl用法做个总结,方便还不太会的同学查阅,如果精通了的同学请直接跳过.
一.流程说明
curl访问站点的大概流程如下:
1).初始化一个新的会话,返回一个curl句柄.
<?php
$curl = curl_init();
?>
<?php
curl_setopt($curl, CURLOPT_URL, $url);
?>
3).执行curl会话.
<?php
$result = curl_exec($curl);
?>
4).关闭curl会话
<?php
curl_close($curl);
?>
当然,还有一些辅助性的函数,例如,使用curl_getinfo获取一个curl连接资源句柄的信息;curl_errno返回最后一次的错误号;curl_error返回最近一次错误的字符串.这些函数,大家可以在自己的逻辑里面酌情调用.至于curl_multi_*系列的多会话操作,暂时不做说明.
二.参数选项详细说明
详见php的官方文档,详见php的官方文档: http://php.net/manual/zh/function.curl-setopt.php.
三.封装curl访问站点
大家可以直接使用我的这个文件来调用微信的api,有谁在此基础上改进优化了,请告诉我.
<?php
//文件名: http://szuzsq.tunnel.qydev.com/weixin/utils.php
/**
* @tutorial 支持http,https
* @param string $url 要访问的站点
* @param array,object $data get只能是key/value的参数集合
* @return 站点数据或失败信息
*/
function curl_http_get($url, $data = null) {
if(isset($data) && (is_array($data) || is_object($data)))
$url = $url . (strpos($url, "?") ? "&" : "?") . http_build_query($data);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //将curl会话获取的信息以字符串返回,而不是直接输出
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //禁止curl验证对等证书(peer's certificate)
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); //不检查服务器SSL证书中是否存在一个公用名(common name)
curl_setopt($curl, CURLOPT_POST, false); //发送 GET请求.类型为:application/x-www-form-urlencoded
//curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //PHP的curl支持通过给此选项传递关联数组(而不是字符串)来生成multipart/form-data的POST请求
$result = curl_exec($curl);
if($errno = curl_errno($curl))
$result = "$errno:" . curl_error($curl);
curl_close($curl);
return $result;
}
/**
* @tutorial 支持http,https
* @param string $url 要访问的站点
* @param mixed $data post可以是任意类型的数据,例如string,array,object,json等
* @return 站点数据或失败信息
*/
function curl_http_post($url, $data) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //将curl会话获取的信息以字符串返回,而不是直接输出
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //禁止curl验证对等证书(peer's certificate)
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); //不检查服务器SSL证书中是否存在一个公用名(common name)
curl_setopt($curl, CURLOPT_POST, true); //发送 POST请求.类型为:application/x-www-form-urlencoded
curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //PHP的curl支持通过给此选项传递关联数组(而不是字符串)来生成multipart/form-data的POST请求
$result = curl_exec($curl);
if($errno = curl_errno($curl))
$result = "$errno:" . curl_error($curl);
curl_close($curl);
return $result;
}
/**
* @tutorial 支持http,https
* @param string $url 要访问的站点
* @param string $field 文件域.微信公众号一般为"media"
* @param string $file 要上传的文件名.可以是相对路径或绝对路径
* @return 站点数据或失败信息
* @see
* ****以下2者的调用方式,效果是一样的:
* ****curl_http_upload("http://localhost/weixin/server.php", "media", "a.jpg");
* ****$ curl -F "media=@a.jpg" "http://localhost/weixin/server.php"
* ****后台得到的$_FILES应该为:
* ****array("media" => array("name" => "a.jpg", "type" => "image/jpeg", "tmp_name" => "C:\wamp\tmp\php9CC4.tmp", "error" => 0, "size" => 46192));
*/
function curl_http_upload($url, $field, $file) {
//传统上,PHP的curl支持通过在数组数据中,使用"@文件全路径"的前缀语法来附加文件,供curl读取上传,这与命令行直接调用curl程序的语法是一致的.
//curl_setopt(curl, CURLOPT_POSTFIELDS, array("media" => "@a.jpg;type=image/jpeg")));
//$ curl -F "media=@a.jpg" "http://localhost/weixin/server.php"
//从PHP5.5.0开始 ,使用@前缀语法在CURLOPT_POSTFIELDS中发送文件已被废弃(PHP推荐使用CURLFile替代旧的@前缀语法)
//而我们仍然可能使用这个语法来上传文件,因而将废弃等提示关闭
$level = error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING ^ E_DEPRECATED); //关闭错误提示
$filename = realpath($file);
$mimetype = mime_content_type($filename); //如果不手动设置$mimetype,curl会默认为"application/octet-stream"
if(class_exists("\CURLFile"))
$data = array($field => new \CURLFile($filename, $mimetype));
else
$data = array($field => "@$filename;type=$mimetype");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //将curl会话获取的信息以字符串返回,而不是直接输出
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //禁止curl验证对等证书(peer's certificate)
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); //不检查服务器SSL证书中是否存在一个公用名(common name)
curl_setopt($curl, CURLOPT_POST, true); //发送 POST请求.类型为:application/x-www-form-urlencoded
if(defined("CURLOPT_SAFE_UPLOAD") && !class_exists("\CURLFile")) //开启@前缀语法在CURLOPT_POSTFIELDS中发送文件.此参数选项在PHP5.5.0中添加,默认值false;PHP5.6.0中默认值改为true
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //PHP的curl支持通过给此选项传递关联数组(而不是字符串)来生成multipart/form-data的POST请求
$result = curl_exec($curl);
if($errno = curl_errno($curl))
$result = "$errno:" . curl_error($curl);
curl_close($curl);
error_reporting($level);
return $result;
}
/**
* @tutorial 支持http,https
* @param string $url 要访问的站点
* @param string $file 保存到本地的文件名,如果需要的话
* @return 站点数据或失败信息.对于下载来说,成功时的站点数据即为文件的二进制内容
* @see
* ****成功返回时:
* ****1).如果提供了$file参数,则文件会直接保存到本地;
* ****2).同时,将文件的二进制内容作为返回值,可灵活用于缩放,旋转,渲染,保存等.
*/
function curl_http_download($url, $file) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //将curl会话获取的信息以字符串返回,而不是直接输出
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //禁止curl验证对等证书(peer's certificate)
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); //不检查服务器SSL证书中是否存在一个公用名(common name)
curl_setopt($curl, CURLOPT_POST, false); //发送 GET请求.类型为:application/x-www-form-urlencoded
curl_setopt($curl, CURLOPT_HEADER, false); //禁止将头文件信息作为数据流输出
curl_setopt($curl, CURLOPT_NOBODY, false); //输出BODY部分
//curl_setopt($curl, CURLOPT_POSTFIELDS, $data); //PHP的curl支持通过给此选项传递关联数组(而不是字符串)来生成multipart/form-data的POST请求
$result = curl_exec($curl);
//$info = curl_getinfo($curl); //curl连接资源句柄的信息.如头信息等
if($errno = curl_errno($curl))
$result = "$errno:" . curl_error($curl);
else if(isset($file))
file_put_contents($file, $result);
curl_close($curl);
return $result;
}
?>