易信通用封装核心类
程序员文章站
2022-07-02 18:55:12
...
网上微信的二次开发教程很多,通用的封装类也很多,但是唯独不好找到易信的通用类,虽然说易信的用户少,但也算是通信阵营的一份子把,博主借鉴了易信公共平台整合库,但是在作者的基础上做了修改,作者原来的是照搬微信的核心通用封装类,不过里面API有些错误,易信是没法调通的,所以我在作者重构了对应的代码,目前在项目中是通过扩展类的形式,给ThinkPHP框架用的之前的。Github的那位作者,如果你能看到这篇文章,请给我留言啊,我还没有提交给这份代码呢。[email protected]
<?php
class YixinChat {
/* 配置参数 */
/* 静态常量 */
const MSGTYPE_TEXT = 'text';
const MSGTYPE_IMAGE = 'image';
const MSGTYPE_LOCATION = 'location';
const MSGTYPE_LINK = 'link';
const MSGTYPE_EVENT = 'event';
const MSGTYPE_MUSIC = 'music';
const MSGTYPE_NEWS = 'news';
const MSGTYPE_VOICE = 'voice';
const MSGTYPE_VIDEO = 'video';
const MSGTYPE_GOODS = 'goods';
const MSGTYPE_CARD = 'card';
const API_URL_PREFIX = 'https://api.yixin.im/cgi-bin';
const AUTH_URL = '/token?grant_type=client_credential&';
const MENU_CREATE_URL = '/menu/create?';
const MENU_GET_URL = '/menu/get?';
const MENU_DELETE_URL = '/menu/delete?';
/* 私有参数 */
private $_msg;
private $_funcflag = false;
public $_receive;
private $_logcallback = null;
private $token;
private $appid;
private $appsecret;
private $access_token;
public $debug = false; //调试开关
/**
* 初始化工作
* @param array $options array('token'=>'易信接口**');
*/
public function __construct($options=array())
{
if (!empty($options))
{
$this->token = isset($options['token'])?$options['token']:'';
$this->appid = isset($options['appid'])?$options['appid']:'';
$this->appsecret = isset($options['appsecret'])?$options['appsecret']:'';
$this->debug = isset($options['debug'])?$options['debug']:false;
$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
}
}
/**
* 验证请求签名操作
* @return boolean
*/
private function checkSignature()
{
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = $this->token;
$tmpArray = array($token, $timestamp, $nonce);
sort($tmpArray);
if(sha1(implode($tmpArray)) == $signature)
{
return true;
}
else
{
return false;
}
}
/**
* 验证当前请求是否有效(可选)
* @param bool $return 是否返回
* @return bool|string
*/
public function valid($return=false)
{
$echoStr = isset($_GET["echostr"])?$_GET["echostr"]: '';
if ($return)
{
if ($echoStr)
{
if ($this->checkSignature())
{
return $echoStr;
}
else
{
return false;
}
}
else
{
return $this->checkSignature();
}
}
else
{
if ($echoStr)
{
if ($this->checkSignature())
{
die($echoStr);
}
else
{
die('No Access');
}
}
else
{
if ($this->checkSignature())
{
return true;
}
else
{
die('No Access');
}
}
}
}
/**
* 设置发送消息
* @param array|string $msg 消息数组
* @param bool $append 是否在原消息数组追加
* @return array
*/
public function Message($msg = array(),$append = false){
if(is_array($msg))
{
if ($append){
$this->_msg = array_merge($this->_msg,$msg);
}
else{
$this->_msg = $msg;
}
return $this->_msg;
}
else
{
return $this->_msg;
}
}
/**
* 设置星标
* @param $flag
* @return $this
*/
public function setFuncFlag($flag) {
$this->_funcflag = $flag;
return $this;
}
/**
* 调试信息日志日记录
* @param $log
* @return mixed|null
*/
private function log($log){
if ($this->debug && function_exists($this->_logcallback)) {
if (is_array($log)) $log = print_r($log,true);
return call_user_func($this->_logcallback,$log);
}
return null;
}
/**
* @name 获取易信服务器发来的信息
* @return mixed
*/
public function getRev()
{
$postStr = file_get_contents("php://input");
$this->log($postStr);
if (!empty($postStr))
{
$this->_receive = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
}
return $this;
}
/**
* 获取消息发送者
* @return string or boolean
*/
public function getRevFrom()
{
if ($this->_receive)
{
return $this->_receive['FromUserName'];
}
else
{
return false;
}
}
/**
* 获取消息接受者
* @return string or boolean
*/
public function getRevTo()
{
if ($this->_receive)
{
return $this->_receive['ToUserName'];
}
else
{
return false;
}
}
/**
* 获取接收消息的类型
*/
public function getRevType()
{
if (isset($this->_receive['MsgType']))
{
return $this->_receive['MsgType'];
}
else
{
return false;
}
}
/**
* 获取消息ID
*/
public function getRevID() {
if (isset($this->_receive['MsgId']))
return $this->_receive['MsgId'];
else
return false;
}
/**
* 获取消息发送时间
*/
public function getRevCtime() {
if (isset($this->_receive['CreateTime']))
{
return $this->_receive['CreateTime'];
}
else{
return false;
}
}
/**
* 获取接收消息内容正文
*/
public function getRevContent(){
if (isset($this->_receive['Content']))
{
return $this->_receive['Content'];
}
else if (isset($this->_receive['Url'])) //获取语音地址,需申请开通
{
return array(
'Url'=>$this->_receive['Url'],
'name'=>$this->_receive['name'],
'mimeType'=>$this->_receive['mimeType']
);
}
else if (isset($this->_receive['url'])) //获取视频地址,需申请开通
{ return array(
'url'=>$this->_receive['url'],
'name'=>$this->_receive['name'],
'mimeType'=>$this->_receive['mimeType']
);
}
else{
return false;
}
}
/**
* 获取接收消息图片
*/
public function getRevPic(){
if (isset($this->_receive['PicUrl'])){
return $this->_receive['PicUrl'];
}
else{
return false;
}
}
/**
* 获取接收消息链接
*/
/**
public function getRevLink(){
if (isset($this->_receive['Url']))
{
return array(
'url'=>$this->_receive['Url'],
'title'=>$this->_receive['Title'],
'description'=>$this->_receive['Description']
);
}
else{
return false;
}
}
/**
* 获取接收语音推送
* @return array|bool
*/
public function getRevVoice()
{
if ($this->_receive['MsgType']=='audio')
{
return array(
'Url'=>$this->_receive['Url'],
'name'=>$this->_receive['name'],
'mimeType'=>$this->_receive['mimeType']
);
}
else
{
return false;
}
}
/**
* 获取接收地理位置
* @return array('x'=>'','y'=>'','scale'=>'','label'=>'')
*/
public function getRevGeo(){
if (isset($this->_receive['Location_X'])){
return array(
'x'=>$this->_receive['Location_X'],
'y'=>$this->_receive['Location_Y'],
'scale'=>$this->_receive['Scale'],
'label'=>$this->_receive['Label']
);
}
else{
return false;
}
}
/**
* 获取上报地理位置事件
*/
public function getRevEventGeo(){
if (isset($this->_receive['Latitude'])){
return array(
'x'=>$this->_receive['Latitude'],
'y'=>$this->_receive['Longitude'],
'precision'=>$this->_receive['Precision'],
);
} else
return false;
}
/**
* 获取接收事件推送
* @return array 成功返回事件数组,失败返回false
*/
public function getRevEvent(){
if (isset($this->_receive['Event'])){
$array['Event'] = $this->_receive['Event'];
}
if (isset($this->_receive['EventKey'])){
$array['EventKey'] = $this->_receive['EventKey'];
}
if (isset($array) && count($array) > 0) {
return $array;
} else {
return false;
}
}
/**
* 获取扫描带参数二维码事件
*
* 事件类型为以下两种时则调用此方法有效
* Event 事件类型,subscribe
* Event 事件类型,scan
*
* @return: array | false
* array (
* 'EventKey'=>'', 事件类型subscribe时候,qrscene_为前缀,后面为二维码的参数值;事件类型scan时候,是一个32位无符号整数
* 'Ticket'=>''
* )
*/
public function getRevScanInfo(){
if(isset($this->_receive['Event']))
{
return array(
'EventKey'=>$this->_receive['EventKey'],
'Ticket'=>$this->_receive['Ticket'],
);
}
}
/**
* 获取接收TICKET
*/
public function getRevTicket(){
if (isset($this->_receive['Ticket'])){
return $this->_receive['Ticket'];
} else
return false;
}
/**
* 获取二维码的场景值
*/
public function getRevSceneId (){
if (isset($this->_receive['EventKey'])){
return str_replace('qrscene_','',$this->_receive['EventKey']);
} else{
return false;
}
}
/**
* XML特殊字符过滤
* @param $str
* @return string
*/
private static function xmlSafeStr($str)
{
return '<![CDATA['.preg_replace("/[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]/",'',$str).']]>';
}
/**
* 数据XML编码
* @param mixed $data 数据
* @return string
*/
private static function data_to_xml($data)
{
$xml = '';
foreach ($data as $key => $val)
{
is_numeric($key) && $key = "item";
$xml .= "<$key>";
$xml .= ( is_array($val) || is_object($val)) ? self::data_to_xml($val) : self::xmlSafeStr($val);
list($key, ) = explode(' ', $key);
$xml .= "</$key>";
}
return $xml;
}
/**
* XML编码
* @param mixed $data 数据
* @param string $root 根节点名
* @param string $item 数字索引的子节点名
* @param string $attr 根节点属性
* @param string $id 数字索引子节点key转换的属性名
* @return string
*/
private function xml_encode($data, $root='xml', $item='item', $attr='', $id='id')
{
if(is_array($attr))
{
$_attr = array();
foreach ($attr as $key => $value)
{
$_attr[] = "{$key}=\"{$value}\"";
}
$attr = implode(' ', $_attr);
}
$attr = trim($attr);
$attr = empty($attr) ? '' : " {$attr}";
$xml = null;
$xml .= "<{$root}{$attr}>";
$xml .= self::data_to_xml($data);
$xml .= "</{$root}>";
return $xml;
}
/**
* 过滤文字回复\r\n换行符
* @param string $text
* @return string|mixed
*/
private function _auto_text_filter($text) {
if (!$this->_text_filter) return $text;
return str_replace("\r\n", "\n", $text);
}
/***********************************************************************************************************************************************************/
/**
* 设置回复消息
* Examle: $obj->text('hello')->reply();
* @param string $text
* @return $this
*/
public function text($text='')
{
$FuncFlag = $this->_funcflag ? 1 : 0;
$msg = array(
'ToUserName' => $this->getRevFrom(),
'FromUserName'=>$this->getRevTo(),
'MsgType'=>self::MSGTYPE_TEXT,
'Content'=>$text,
'CreateTime'=>time()
);
$this->Message($msg);
return $this;
}
/**
* 设置回复音乐
* @param string $title
* @param string $desc
* @param string $musicurl
* @param string $hgmusicurl
* @return $this
*/
public function music($title,$desc,$musicurl,$hgmusicurl='') {
$FuncFlag = $this->_funcflag ? 1 : 0;
$msg = array(
'ToUserName' => $this->getRevFrom(),
'FromUserName'=>$this->getRevTo(),
'CreateTime'=>time(),
'MsgType'=>self::MSGTYPE_MUSIC,
'Music'=>array(
'Title'=>$title,
'Description'=>$desc,
'MusicUrl'=>$musicurl,
'HQMusicUrl'=>$hgmusicurl
)
);
$this->Message($msg);
return $this;
}
/**
* 设置回复图文
* @param array $newsData
* @return $this
* @example 数组结构:
* array(
* 0=>array(
* 'Title'=>'msg title',
* 'Description'=>'summary text',
* 'PicUrl'=>'http://www.domain.com/1.jpg',
* 'Url'=>'http://www.domain.com/1.html'
* ),
* 1=>....
* )
*/
public function news($newsData=array())
{
$FuncFlag = $this->_funcflag ? 1 : 0;
$count = count($newsData);
$msg = array(
'ToUserName' => $this->getRevFrom(),
'FromUserName'=>$this->getRevTo(),
'CreateTime'=>time(),
'MsgType'=>self::MSGTYPE_NEWS,
'ArticleCount'=>$count,
'Articles'=>$newsData
);
$this->Message($msg);
return $this;
}
/**
*
* 向易信服务器回复消息
* Example: $this->text('msg tips')->reply();
* @param array|string $msg 要发送的信息, 默认取$this->_msg
* @param bool $return 是否返回信息而输出 默认:false
* @return string
*/
public function reply($msg=array(),$return = false)
{
if (empty($msg))
{
$msg = $this->_msg;
}
$xmldata= $this->xml_encode($msg);
$this->log($xmldata);
if ($return)
{
return $xmldata;
}
else
{
echo $xmldata;
}
}
private static function getTextArea($text,$str_start,$str_end){
if(empty($text)||empty($str_start))
{
return false;
}
[email protected]($text,$str_start);
if($start_pos===false){
return false;
}
$end_pos=strpos($text,$str_end, $start_pos);
if($end_pos>$start_pos && $end_pos!==false)
{
$begin_pos=$start_pos+strlen($str_start);
return substr($text, $begin_pos,$end_pos-$begin_pos);
}
else
{
return false;
}
}
/**
* GET 请求
* @param string $url
*/
private function http_get($url){
//$proxy_url = "http://10.1.255.24:8090";
$oCurl = curl_init();
if(stripos($url,"https://")!==FALSE){
//curl_setopt($oCurl, CURLOPT_PROXY, $proxy_url);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if(intval($aStatus["http_code"])==200){
return $sContent;
}else{
return false;
}
}
/**
* POST 请求
* @param string $url
* @param array $param
* @param boolean $post_file 是否文件上传
* @return string content
*/
private function http_post($url,$param,$post_file=false){
//$proxy_url = "http://10.1.255.24:8090";
$oCurl = curl_init();
if(stripos($url,"https://")!==FALSE){
//curl_setopt($oCurl, CURLOPT_PROXY, $proxy_url);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
if (is_string($param) || $post_file) {
$strPOST = $param;
} else {
$aPOST = array();
foreach($param as $key=>$val){
$aPOST[] = $key."=".urlencode($val);
}
$strPOST = join("&", $aPOST);
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($oCurl, CURLOPT_POST,true);
curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if(intval($aStatus["http_code"])==200){
return $sContent;
}else{
return false;
}
}
/**
* 通用auth验证方法,暂时仅用于菜单更新操作
* @param string $appid
* @param string $appsecret
*/
public function checkAuth($appid='',$appsecret=''){
if (!$appid || !$appsecret) {
$appid = $this->appid;
$appsecret = $this->appsecret;
}
$result = $this->http_get(self::API_URL_PREFIX.self::AUTH_URL.'appid='.$appid.'&secret='.$appsecret);
if ($result)
{
$json = json_decode($result,true);
if (!$json || isset($json['errcode'])) {
$this->errCode = $json['errcode'];
$this->errMsg = $json['errmsg'];
return false;
}
$this->access_token = $json['access_token'];
$expire = $json['expires_in'] ? intval($json['expires_in'])-100 : 3600;
S('authname',$this->access_token,$expire);
return $this->access_token;
}
return false;
}
/**
* 删除验证数据
* @param string $appid
*/
public function resetAuth($appid=''){
if (!$appid) $appid = $this->appid;
$this->access_token = '';
$authname = 'wechat_access_token'.$appid;
S($authname,null);
return true;
}
/**
* 微信api不支持中文转义的json结构 /JSON编码
* @param array $arr
*/
/**
static function json_encode($arr)
{
$parts = array ();
$is_list = false;
//Find out if the given array is a numerical array
$keys = array_keys ( $arr );
$max_length = count ( $arr ) - 1;
if (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //See if the first key is 0 and last key is length - 1
$is_list = true;
for($i = 0; $i < count ( $keys ); $i ++) { //See if each key correspondes to its position
if ($i != $keys [$i]) { //A key fails at position check.
$is_list = false; //It is an associative array.
break;
}
}
}
foreach ( $arr as $key => $value ) {
if (is_array ( $value )) { //Custom handling for arrays
if ($is_list)
$parts [] = self::json_encode ( $value );
else
$parts [] = '"' . $key . '":' . self::json_encode ( $value );
} else {
$str = '';
if (! $is_list)
$str = '"' . $key . '":';
//Custom handling for multiple data types
if (is_numeric ( $value ) && $value<2000000000)
$str .= $value; //Numbers
elseif ($value === false)
$str .= 'false'; //The booleans
elseif ($value === true)
$str .= 'true';
else
$str .= '"' . addslashes ( $value ) . '"'; //All other things
// :TODO: Is there any more datatype we should be in the lookout for? (Object?)
$parts [] = $str;
}
}
$json = implode ( ',', $parts );
if ($is_list)
return '[' . $json . ']'; //Return numerical JSON
return '{' . $json . '}'; //Return associative JSON
}
**/
/**
* 创建菜单
* @param array $data 菜单数组数据
* example:
* array (
* 'button' => array (
* 0 => array (
* 'name' => '扫码',
* 'sub_button' => array (
* 0 => array (
* 'key' => 'rselfmenu_0_0',
* 'name' => '扫码带提示',
'type' => 'scancode_waitmsg'
* ),
* 1 => array (
'key' => 'rselfmenu_0_1',
'name' => '扫码推事件',
* 'type' => 'scancode_push' *
* )
* ),
* ),
* 1 => array (
* 'name' => '发图',
* 'sub_button' => array (
* 0 => array (
* 'key' => 'rselfmenu_0_0',
* 'name' => '扫码带提示',
'type' => 'scancode_waitmsg'
* ),
* 1 => array (
'key' => 'rselfmenu_0_1',
'name' => '扫码推事件',
* 'type' => 'scancode_push' *
* )
* ),
* ),
* 2 => array (
* 'key' => 'rselfmenu_0_1',
'name' => '扫码推事件',
* 'type' => 'scancode_push'
* ),
* ),
* );
* type可以选择为以下2种
* 1、click:点击推事件
* 2、view:跳转URL
*/
public function createMenu($data){
header("Content-type:text/html;charset=utf-8");
if (!$this->access_token && !$this->checkAuth()) return false;
$result = $this->http_post(self::API_URL_PREFIX.self::MENU_CREATE_URL.'access_token='.$this->access_token,json_encode($data));
if ($result)
{
$json = json_decode($result,true);
if (!$json || !empty($json['errcode'])) {
$this->errCode = $json['errcode'];
$this->errMsg = $json['errmsg'];
return false;
}
return true;
}
return false;
}
/**
* 获取菜单
* @return array('menu'=>array(....s))
*/
public function getMenu(){
header("Content-type:text/html;charset=utf-8");
if (!$this->access_token && !$this->checkAuth()) return false;
$result = $this->http_get(self::API_URL_PREFIX.self::MENU_GET_URL.'access_token='.$this->access_token);
if ($result)
{
$json = json_decode($result,true);
if (!$json || isset($json['errcode'])) {
$this->errCode = $json['errcode'];
$this->errMsg = $json['errmsg'];
return false;
}
return $json;
}
return false;
}
/**
* 删除菜单
* @return boolean
*/
public function deleteMenu(){
header("Content-type:text/html;charset=utf-8");
if (!$this->access_token && !$this->checkAuth()) return false;
$result = $this->http_get(self::API_URL_PREFIX.self::MENU_DELETE_URL.'access_token='.$this->access_token);
if ($result)
{
$json = json_decode($result,true);
if (!$json || !empty($json['errcode'])) {
$this->errCode = $json['errcode'];
$this->errMsg = $json['errmsg'];
return false;
}
return true;
}
return false;
}
}
/**
* Rolling Curl Request Class
* @author Ligboy ([email protected])
* @copyright
* @example
*
*
*/
class CurlHttp {
/* 单线程请求设置项 */
/* 并发请求设置项 */
private $limitCount = 10; //并发请求数量
public $returninfoswitch = false; //是否返回请求信息,开启后单项请求返回结果为:array('info'=>请求信息, 'result'=>返回内容, 'error'=>错误信息)
//私有属性
private $singlequeue = null;
private $rollqueue = null;
private $_requstItems = null;
private $_callback = null;
private $_result;
private $_referer = null;
private $_cookies = array();
private $_resheader;
private $_reqheader = array();
private $_resurl;
private $_redirect_url;
private $referer;
private $_singleoptions = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => true, // don't return headers
// CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_NOSIGNAL =>true,
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_USERAGENT => "", // who am i
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
CURLOPT_SSL_VERIFYHOST => 0, // don't verify ssl
CURLOPT_SSL_VERIFYPEER => false, //
);
private $_rolloptions = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // don't return headers
// CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_NOSIGNAL =>true,
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_USERAGENT => "", // who am i
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
CURLOPT_SSL_VERIFYHOST => 0, // don't verify ssl
CURLOPT_SSL_VERIFYPEER => false, //
);
function singleInit($options = array()) {
if (!$this->singlequeue) {
$this->singlequeue = curl_init();
}
if ($options) {
$this->_singleoptions = array_merge($this->_singleoptions, $options);
}
}
function rollInit($options = array()) {
if(!$this->rollqueue){
$this->rollqueue = curl_multi_init();
}
if ($options) {
$this->_rolloptions = array_merge($this->_rolloptions, $options);
}
}
/**
* @name 返回Header数组
* @param resource $ch
* @param $result
* @return string
*/
private function getResRawHeader($ch, $result) {
$ch_info = curl_getinfo($ch);
$header_size = $ch_info["header_size"];
$rawheader = substr($result, 0, $ch_info['header_size']);
return $rawheader;
}
/**
* @name 返回Header数组
* @param resource $ch
* @param $result
* @return string
*/
private function getResHeader($ch, $result) {
$header = array();
$rawheader = $this->getResRawHeader($ch, $result);
if(preg_match_all('/([^:\s]+): (.*)/i', $rawheader, $header_match)){
for($i=0;$i<count($header_match[0]);$i++){
$header[$header_match[1][$i]] = $header_match[2][$i];
}
}
return $header;
}
/**
* @name 返回网页主体内容
* @param resource $ch
* @param $result
* @return string 网页主体内容
*/
private function getResBody($ch, $result) {
$ch_info = curl_getinfo($ch);
$body = substr($result, -$ch_info['download_content_length']);
return $body;
}
/**
* @name 返回网页主体内容
* @param resource $ch
* @param $result
* @return array 网页主体内容
*/
private function getResCookies($ch, $result) {
$rawheader = $this->getResRawHeader($ch, $result);
$cookies = array();
if(preg_match_all('/Set-Cookie:(?:\s*)([^=]*?)=([^\;]*?);/i', $rawheader, $cookie_match)){
for($i=0;$i<count($cookie_match[0]);$i++){
$cookies[$cookie_match[1][$i]] = $cookie_match[2][$i];
}
}
return $cookies;
}
private function setReqCookies($ch, $reqcookies = array()) {
$reqCookiesString = "";
if(!empty($reqcookies)){
if(is_array($reqcookies)){
foreach ($reqcookies as $key => $val){
$reqCookiesString .= $key."=".$val."; ";
}
curl_setopt($ch, CURLOPT_COOKIE, $reqCookiesString);
}
}elseif(!empty($this->_cookies)) {
foreach ($this->_cookies as $key => $val){
$reqCookiesString .= $key."=".$val."; ";
}
curl_setopt($ch, CURLOPT_COOKIE, $reqCookiesString);
}
}
private function setResCookies($ch) {
if(!empty($reqcookies)&&is_array($reqcookies)){
$this->_cookies = array_merge($this->_cookies, $reqcookies);
}
}
/**
* @param unknown $url
* @param mixed $postfields
* @param string $referer
* @param array $reqcookies
* @param array $reqheader
* @return unknown
*/
function post($url, $postfields=null, $referer=null, $reqcookies=null, $reqheader=array())
{
$this->singlequeue = curl_init($url);
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => true, // don't return headers
// CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_USERAGENT => "", // who am i
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
CURLOPT_POST => true, // i am sending post data
CURLOPT_SSL_VERIFYHOST => 0, // don't verify ssl
CURLOPT_SSL_VERIFYPEER => false, //
);
curl_setopt_array($this->singlequeue, $options);
curl_setopt($this->singlequeue, CURLOPT_POSTFIELDS, $postfields); // this are my post vars
if($referer){
curl_setopt($this->singlequeue, CURLOPT_REFERER, $referer);
}
elseif ($this->referer){
curl_setopt($this->singlequeue, CURLOPT_REFERER, $this->referer);
}
$this->setReqheader($this->singlequeue, $reqheader);
$this->setReqCookies($this->singlequeue, $reqcookies);
$result = curl_exec($this->singlequeue);
$resCookies = $this->getResCookies($this->singlequeue, $result);;
if (is_array($resCookies)&&!empty($resCookies)) {
$this->_cookies = array_merge($this->_cookies ,$resCookies);
}
$resHeader = $this->getResHeader($this->singlequeue, $result);
if (is_array($resHeader)&&!empty($resHeader)) {
$this->_resheader = $resHeader;
}
$this->_result = $this->getResBody($this->singlequeue, $result);
curl_close($this->singlequeue);
$this->singlequeue = null;
return $this->_result;
}
/**
* @param unknown $url
* @param unknown $referer
* @param null $reqcookies
* @param array $reqheader
* @return unknown
*/
function get($url, $referer=null, $reqcookies=null, $reqheader=array())
{
$this->singlequeue = curl_init($url);
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => true, // don't return headers
// CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_USERAGENT => "", // who am i
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
CURLOPT_POST => false, // i am sending post data
CURLOPT_SSL_VERIFYHOST => 0, // don't verify ssl
CURLOPT_SSL_VERIFYPEER => false, //
CURLOPT_REFERER =>$referer,
);
curl_setopt_array($this->singlequeue, $options);
if($referer){
curl_setopt($this->singlequeue, CURLOPT_REFERER, $referer);
}
elseif ($this->referer){
curl_setopt($this->singlequeue, CURLOPT_REFERER, $this->referer);
}
$this->setReqheader($this->singlequeue, $reqheader);
$this->setReqCookies($this->singlequeue, $reqcookies);
$result = curl_exec($this->singlequeue);
$resCookies = $this->getResCookies($this->singlequeue, $result);
if (is_array($resCookies)&&!empty($resCookies)) {
$this->_cookies = array_merge($this->_cookies ,$resCookies);
}
$resHeader = $this->getResHeader($this->singlequeue, $result);
if (is_array($resHeader)) {
$this->_resheader = $resHeader;
}
$this->_result = $this->getResBody($this->singlequeue, $result);
curl_close($this->singlequeue);
$this->singlequeue = null;
return $this->_result;
}
/**
* 并发行的curl方法
* @param unknown $requestArray
* @param string $callback
* @return multitype:multitype:
*/
function rollRequest($requestArray, $callback="")
{
$this->_requstItems = $requestArray;
$requestArrayKeys = array_keys($requestArray);
$this->rollqueue = curl_multi_init();
$map = array();
for ($i=0;$i<$this->limitCount && !empty($requestArrayKeys);$i++)
{
$keyvalue = array_shift($requestArrayKeys);
$this->addToRollQueue( $requestArray, $keyvalue, $map );
}
$responses = array();
do {
while (($code = curl_multi_exec($this->rollqueue, $active)) == CURLM_CALL_MULTI_PERFORM) ;
if ($code != CURLM_OK) { break; }
// 找到刚刚完成的任务句柄
while ($done = curl_multi_info_read($this->rollqueue)) {
// 处理当前句柄的信息、错误、和返回内容
$info = curl_getinfo($done['handle']);
$error = curl_error($done['handle']);
if ($this->_callback)
{
//调用callback函数处理当前句柄的返回内容,callback函数参数有:(返回内容, 队列id)
$result = call_user_func($this->_callback, curl_multi_getcontent($done['handle']), $map[(string) $done['handle']]);
}
else
{
//如果callback为空,直接返回内容
$result = curl_multi_getcontent($done['handle']);
}
if ($this->returninfoswitch) {
$responses[$map[(string) $done['handle']]] = compact('info', 'error', 'result');
}
else
{
$responses[$map[(string) $done['handle']]] = $result;
}
// 从队列里移除上面完成处理的句柄
curl_multi_remove_handle($this->rollqueue, $done['handle']);
curl_close($done['handle']);
if (!empty($requestArrayKeys))
{
$addkey = array_shift($requestArrayKeys);
$this->addToRollQueue ( $requestArray, $addkey, $map );
}
}
// Block for data in / output; error handling is done by curl_multi_exec
if ($active > 0) {
curl_multi_select($this->rollqueue, 0.5);
}
} while ($active);
curl_multi_close($this->rollqueue);
$this->rollqueue = null;
return $responses;
}
/**
* @param requestArray
* @param map
* @param keyvalue
*/
private function addToRollQueue($requestArray, $keyvalue, &$map) {
$ch = curl_init();
curl_setopt_array($ch, $this->_rolloptions);
//检查提交方式,并设置对应的设置,为空的话默认采用get方式
if ("post" === $requestArray[$keyvalue]['method'])
{
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestArray[$keyvalue]['postfields']);
}
else
{
curl_setopt($ch, CURLOPT_HTTPGET, true);
}
if($requestArray[$keyvalue]['referer']){
curl_setopt($ch, CURLOPT_REFERER, $requestArray[$keyvalue]['referer']);
}
elseif ($this->referer){
curl_setopt($ch, CURLOPT_REFERER, $this->referer);
}
$this->setReqheader($ch, $requestArray[$keyvalue]['header']);
//cookies设置
$this->setReqCookies($ch, $requestArray[$keyvalue]['cookies']);
curl_setopt($ch, CURLOPT_URL, $requestArray[$keyvalue]['url']);
curl_setopt($ch, CURLOPT_REFERER, $requestArray[$keyvalue]['referer']);
curl_multi_add_handle($this->rollqueue, $ch);
$map[(string) $ch] = $keyvalue;
}
/**
* 返回当前并行数
* @return the $limitCount
*/
public function getRollLimitCount() {
return $this->limitCount;
}
/**
* 设置并发性请求数量
* @param number $limitCount
* @return $this
*/
public function setRollLimitCount($limitCount) {
$this->limitCount = $limitCount;
return $this;
}
/**
* 设置回调函数
* @param field_type $_callback
* @return $this
*/
public function setCallback($_callback) {
$this->_callback = $_callback;
return $this;
}
public function getResult() {
return $this->_result;
}
public function getRawHeader() {
return $this->_resheader;
}
public function getCookies() {
return $this->_cookies;
}
public function setCookies($_cookies) {
$this->_cookies = $_cookies;
return $this;
}
/**
* @param $header
* @return $this
*/
public function setHeader($header) {
$this->_reqheader = array_merge($this->_reqheader, $header);
return $this;
}
/**
* @param resource $ch
* @param array $reqheader
* @return $this
*/
private function setReqheader($ch, $reqheader) {
$reqheader = array_merge($this->_reqheader, $reqheader);
if (is_array($reqheader)) {
$rawReqHeader = array();
foreach ($reqheader as $key => $value){
$rawReqHeader[] = "$key: $value";
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $rawReqHeader);
$this->_reqheader = array();
}
return $this;
}
}
/**
* error code
* 仅用作类内部使用,不用于官方API接口的errCode码
*/
class ErrorCode
{
public static $OK = 0;
public static $ValidateSignatureError = 40001;
public static $ParseXmlError = 40002;
public static $ComputeSignatureError = 40003;
public static $IllegalAesKey = 40004;
public static $ValidateAppidError = 40005;
public static $EncryptAESError = 40006;
public static $DecryptAESError = 40007;
public static $IllegalBuffer = 40008;
public static $EncodeBase64Error = 40009;
public static $DecodeBase64Error = 40010;
public static $GenReturnXmlError = 40011;
public static $errCode=array(
'0'=>'请求成功',
'40001'=>'验证失败',
'40002'=>'不合法的凭证类型',
'40003'=>'不合法的OpenID',
'40004'=>'不合法的媒体文件类型',
'40005'=>'不合法的文件类型',
'40006'=>'不合法的文件大小',
'40007'=>'不合法的媒体文件id',
'40008'=>'不合法的消息类型',
'40009'=>'不合法的图片文件大小',
'40010'=>'不合法的语音文件大小',
'40011'=>'不合法的视频文件大小',
'40012'=>'不合法的缩略图文件大小',
'40013'=>'不合法的APPID',
'40014'=>'不合法的access_token',
'40015'=>'不合法的菜单类型',
'40016'=>'不合法的按钮个数',
'40018'=>'不合法的按钮名字长度',
'40019'=>'不合法的按钮KEY长度',
'40020'=>'不合法的按钮URL长度',
'40021'=>'不合法的菜单版本号',
'40022'=>'不合法的子菜单级数',
'40023'=>'不合法的子菜单按钮个数',
'40024'=>'不合法的子菜单按钮类型',
'40025'=>'不合法的子菜单按钮名字长度',
'40026'=>'不合法的子菜单按钮KEY长度',
'40027'=>'不合法的子菜单按钮URL长度',
'40028'=>'不合法的自定义菜单使用用户',
'40029'=>'access_token超时',
'40030'=>'refresh_token超时',
'40035'=>'不合法的参数',
'40038'=>'不合法的请求格式',
'40039'=>'不合法的URL长度',
'40050'=>'不合法的分组id',
'40051'=>'分组名字不合法',
'40052'=>'已有重复的分组名称',
'40053'=>'不存在的分组名',
'40054'=>'不允许对黑名单分组群发',
'40998'=>'未授权的API',
'40999'=>'非法IP访问',
'41001'=>'缺少access_token参数',
'41002'=>'缺少appid参数',
'41003'=>'缺少refresh_token参数',
'41004'=>'缺少secret参数',
'41005'=>'缺少多媒体文件数据',
'41006'=>'缺少media_id参数',
'41007'=>'缺少子菜单数据',
'41009'=>'缺少openid',
'42001'=>'access_token超时',
'42008'=>'用户ID不一致',
'42009'=>'APPID不一致',
'43001'=>'需要GET请求',
'43002'=>'需要POST请求',
'43003'=>'需要HTTPS请求',
'43004'=>'需要接收者关注',
'44001'=>'多媒体文件为空',
'44002'=>'POST的数据包为空',
'44003'=>'图文消息内容为空',
'44004'=>'文本消息内容为空',
'45001'=>'多媒体文件大小超过限制',
'45002'=>'消息内容超过限制',
'45003'=>'标题字段超过限制',
'45004'=>'描述字段超过限制',
'45005'=>'链接字段超过限制',
'45006'=>'图片链接字段超过限制',
'45007'=>'语音播放时间超过限制',
'45008'=>'图文消息超过限制',
'45009'=>'接口调用超过限制',
'45010'=>'创建菜单个数超过限制',
'45016'=>'系统分组,不允许修改',
'45017'=>'分组名字过长',
'45018'=>'分组数量超过上限',
'45019'=>'分组名称为空',
'45020'=>'不存在的分组',
'45021'=>'群发消息量超过限制',
'45999'=>'接口调用超过每秒限制',
'46001'=>'不存在媒体数据',
'46002'=>'不存在的菜单版本',
'46003'=>'不存在的菜单数据',
'46004'=>'不存在的用户',
'47001'=>'解析JSON/XML内容错误',
'48001'=>'api功能未授权',
'49000'=>'创建投票活动失败(不合法的请求消息)',
'49001'=>'不合法的投票标题',
'49002'=>'不合法的投票说明',
'49003'=>'不合法的投票结果类型',
'49004'=>'不合法的投票选项个数',
'49005'=>'不合法的投票选项',
'49006'=>'不合法的投票选项类型',
'49007'=>'不合法的投票选择范围',
'49008'=>'不合法的投票截止时间',
'49009'=>'不合法的投票限制类型',
'49010'=>'不存在的投票活动',
'49011'=>'投票结果正在处理',
'49012'=>'投票已结束',
'49013'=>'投票未结束',
'50001'=>'该用户没有关注此公众号',
'50002'=>'该用户不允许公众号获取他的好友关系',
'50003'=>'识别条形码失败',
'50005'=>'无法识别该条形码',
'50006'=>'无法打开所提供的图片链接地址',
'50007'=>'next_openid未关注此公众号',
'50008'=>'生成二维码失败(错误的请求内容)',
'50009'=>'生成二维码失败',
'50010'=>'不合法的ticket',
'51001'=>'不合法的mobile',
'52001'=>'无权访问该动态或该动态不存在',
'52029'=>'发送的内容涉及敏感词',
'60001'=>'请求参数中缺少key',
'60002'=>'公众号不存在',
'60003'=>'公众号状态错误',
'60004'=>'用户在黑名单中'
);
public static function getErrText($err) {
if (isset(self::$errCode[$err])) {
return self::$errCode[$err];
}else {
return false;
};
}
}
转载于:https://my.oschina.net/cometlj/blog/367392
上一篇: vue中的$event