由于没有用composer自动加载,在项目根下写了一个自动加载的index.php入口
<?php
/**
* Created by PhpStorm.
* User: guobao
* Date: 2018/7/29
* Time: 下午7:14
*/
function myAutoload($name){
include str_replace('\\','/',$name) . '.php';
}
spl_autoload_register('myAutoload');
(new \app\Entry())->handle();
创建app文件夹并创建Entry.php
<?php
namespace app;
use wx\core\Button;
use wx\core\JsSdk;
use wx\core\Message;
use wx\core\User;
use wx\Wx;
/**
* Created by PhpStorm.
* User: guobao
* Date: 2018/7/29
* Time: 下午7:18
*/
class Entry
{
public function __construct()
{
$config = [
'token' => '' ,
'appID' => "" ,
'appsecret' => "" ,
];
(new Wx($config))->valid();
}
public function handle()
{
//执行接收用户发送过来的信息,保存到临时文件message.php
// $message = (new Wx())->message();
// file_put_contents('message.php', var_export($message, true));
// (new Message())->autoText('我是张国宝');
// (new Message())->autoImg($message->MediaId);
//关键词自动回复
// if($message->content == '你好'){
// (new Wx())->message('你好');
// }else if($message->content == '你是'){
// (new Wx())->message('你是');
// }
//关注微信自动回复
// if((new Message())->isSubscribe()){
// (new Message())->autoText('欢迎关注');
// }
//取消关注
// if((new Message())->isUnsubscribe()) {
// //删除用户,或者给个标识(字段)
// }
$res = (new Wx())->getAccessToken();
// print_r($res);
// 2.按钮删除
// $res = $this->wx->instance('button')->flush();
// var_dump($res);
// 1.按钮添加
// $str = '{
// "button":[
// {
// "type":"view",
// "name":"后盾网",
// "url":"https://www.baidu.com"
// },
// {
// "name":"菜单",
// "sub_button":[
// {
// "type":"view",
// "name":"后盾人",
// "url":"http://www.houdunren.com/"
// },
// {
// "type":"click",
// "name":"赞一下我们",
// "key":"V1001_GOOD"
// }]
// }]
// }';
// $res =(new Button())->create($str);
// var_dump($res);
// $res =(new Button())->flush();
// var_dump($res);
// $res = (new Button())->getButton();
// $res = (new User())->getTag();
// $post = '{
// "openid":"o5Xhp1Af7sNc4ABjgdZsOHE4X0Gg",
// "remark":"pangzi"
//}';
// $res = (new User())->setName($post);
// $res = (new User())->getUserInfo('o5Xhp1Af7sNc4ABjgdZsOHE4X0Gg');
// $res = (new User())->userInfoList($post);
// var_dump($res);
// 测试引入模板
$data = (new JsSdk())->makeSign();
// print_r($data);
include 'view/index.php';
}
}
创建wechat文件夹并创建Error.php微信错误类
<?php namespace wx;
/**
* 错误
* Class Error
* @package wechat
*/
class Error{
protected $error = [
'-1' => '系统繁忙,此时请开发者稍候再试' ,
0 => '请求成功' ,
40001 => '获取access_token时AppSecret错误,或者access_token无效。请开发者认真比对AppSecret的正确性,或查看是否正在为恰当的公众号调用接口' ,
40002 => '不合法的凭证类型' ,
40003 => '不合法的OpenID,请开发者确认OpenID(该用户)是否已关注公众号,或是否是其他公众号的OpenID' ,
40004 => '不合法的媒体文件类型' ,
40005 => '不合法的文件类型' ,
40006 => '不合法的文件大小' ,
40007 => '不合法的媒体文件id' ,
40008 => '不合法的消息类型' ,
40009 => '不合法的图片文件大小' ,
40010 => '不合法的语音文件大小' ,
40011 => '不合法的视频文件大小' ,
40012 => '不合法的缩略图文件大小' ,
40013 => '不合法的AppID,请开发者检查AppID的正确性,避免异常字符,注意大小写' ,
40014 => '不合法的access_token,请开发者认真比对access_token的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口' ,
40015 => '不合法的菜单类型' ,
40016 => '不合法的按钮个数' ,
40017 => '不合法的按钮个数' ,
40018 => '不合法的按钮名字长度' ,
40019 => '不合法的按钮KEY长度' ,
40020 => '不合法的按钮URL长度' ,
40021 => '不合法的菜单版本号' ,
40022 => '不合法的子菜单级数' ,
40023 => '不合法的子菜单按钮个数' ,
40024 => '不合法的子菜单按钮类型' ,
40025 => '不合法的子菜单按钮名字长度' ,
40026 => '不合法的子菜单按钮KEY长度' ,
40027 => '不合法的子菜单按钮URL长度' ,
40028 => '不合法的自定义菜单使用用户' ,
40029 => '不合法的oauth_code' ,
40030 => '不合法的refresh_token' ,
40031 => '不合法的openid列表' ,
40032 => '不合法的openid列表长度' ,
40033 => '不合法的请求字符,不能包含\uxxxx格式的字符' ,
40035 => '不合法的参数' ,
40038 => '不合法的请求格式' ,
40039 => '不合法的URL长度' ,
40050 => '不合法的分组id' ,
40051 => '分组名字不合法' ,
40117 => '分组名字不合法' ,
40118 => 'media_id大小不合法' ,
40119 => 'button类型错误' ,
40120 => 'button类型错误' ,
40121 => '不合法的media_id类型' ,
40132 => '微信号不合法' ,
40137 => '不支持的图片格式' ,
40155 => '请勿添加其他公众号的主页链接' ,
41001 => '缺少access_token参数' ,
41002 => '缺少appid参数' ,
41003 => '缺少refresh_token参数' ,
41004 => '缺少secret参数' ,
41005 => '缺少多媒体文件数据' ,
41006 => '缺少media_id参数' ,
41007 => '缺少子菜单数据' ,
41008 => '缺少oauth code' ,
41009 => '缺少openid' ,
42001 => 'access_token超时,请检查access_token的有效期,请参考基础支持-获取access_token中,对access_token的详细机制说明' ,
42002 => 'refresh_token超时' ,
42003 => 'oauth_code超时' ,
42007 => '用户修改微信密码,accesstoken和refreshtoken失效,需要重新授权' ,
43001 => '需要GET请求' ,
43002 => '需要POST请求' ,
43003 => '需要HTTPS请求' ,
43004 => '需要接收者关注' ,
43005 => '需要好友关系' ,
43019 => '需要将接收者从黑名单中移除' ,
44001 => '多媒体文件为空' ,
44002 => 'POST的数据包为空' ,
44003 => '图文消息内容为空' ,
44004 => '文本消息内容为空' ,
45001 => '多媒体文件大小超过限制' ,
45002 => '消息内容超过限制' ,
45003 => '标题字段超过限制' ,
45004 => '描述字段超过限制' ,
45005 => '链接字段超过限制' ,
45006 => '图片链接字段超过限制' ,
45007 => '语音播放时间超过限制' ,
45008 => '图文消息超过限制' ,
45009 => '接口调用超过限制' ,
45010 => '创建菜单个数超过限制' ,
45011 => 'API调用太频繁,请稍候再试' ,
45015 => '回复时间超过限制' ,
45016 => '系统分组,不允许修改' ,
45017 => '分组名字过长' ,
45018 => '分组数量超过上限' ,
45047 => '客服接口下行条数超过上限' ,
46001 => '不存在媒体数据' ,
46002 => '不存在的菜单版本' ,
46003 => '不存在的菜单数据' ,
46004 => '不存在的用户' ,
47001 => '解析JSON/XML内容错误' ,
48001 => 'api功能未授权,请确认公众号已获得该接口,可以在公众平台官网-开发者中心页中查看接口权限' ,
48002 => '粉丝拒收消息(粉丝在公众号选项中,关闭了“接收消息”)' ,
48004 => 'api接口被封禁,请登录mp.weixin.qq.com查看详情' ,
48005 => 'api禁止删除被自动回复和自定义菜单引用的素材' ,
48006 => 'api禁止清零调用次数,因为清零次数达到上限' ,
50001 => '用户未授权该api' ,
50002 => '用户受限,可能是违规后接口被封禁' ,
61451 => '参数错误(invalid parameter)' ,
61452 => '无效客服账号(invalid kf_account)' ,
61453 => '客服帐号已存在(kf_account exsited)' ,
61454 => '客服帐号名长度超过限制(仅允许10个英文字符,不包括@及@后的公众号的微信号)(invalid kf_acount length)' ,
61455 => '客服帐号名包含非法字符(仅允许英文+数字)(illegal character in kf_account)' ,
61456 => '客服帐号个数超过限制(10个客服账号)(kf_account count exceeded)' ,
61457 => '无效头像文件类型(invalid file type)' ,
61450 => '系统错误(system error)' ,
61500 => '日期格式错误' ,
65301 => '不存在此menuid对应的个性化菜单' ,
65302 => '没有相应的用户' ,
65303 => '没有默认菜单,不能创建个性化菜单' ,
65304 => 'MatchRule信息为空' ,
65305 => '个性化菜单数量受限' ,
65306 => '不支持个性化菜单的帐号' ,
65307 => '个性化菜单信息为空' ,
65308 => '包含没有响应类型的button' ,
65309 => '个性化菜单开关处于关闭状态' ,
65310 => '填写了省份或城市信息,国家信息不能为空' ,
65311 => '填写了城市信息,省份信息不能为空' ,
65312 => '不合法的国家信息' ,
65313 => '不合法的省份信息' ,
65314 => '不合法的城市信息' ,
65316 => '该公众号的菜单设置了过多的域名外跳(最多跳转到3个域名的链接)' ,
65317 => '不合法的URL' ,
9001001 => 'POST数据参数不合法' ,
9001002 => '远端服务不可用' ,
9001003 => 'Ticket不合法' ,
9001004 => '获取摇周边用户信息失败' ,
9001005 => '获取商户信息失败' ,
9001006 => '获取OpenID失败' ,
9001007 => '上传文件缺失' ,
9001008 => '上传素材的文件类型不合法' ,
9001009 => '上传素材的文件尺寸不合法' ,
9001010 => '上传失败' ,
9001020 => '帐号不合法' ,
9001021 => '已有设备激活率低于50%,不能新增设备' ,
9001022 => '设备申请数不合法,必须为大于0的数字' ,
9001023 => '已存在审核中的设备ID申请' ,
9001024 => '一次查询设备ID数量不能超过50' ,
9001025 => '设备ID不合法' ,
9001026 => '页面ID不合法' ,
9001027 => '页面参数不合法' ,
9001028 => '一次删除页面ID数量不能超过10' ,
9001029 => '页面已应用在设备中,请先解除应用关系再删除' ,
9001030 => '一次查询页面ID数量不能超过50' ,
9001031 => '时间区间不合法' ,
9001032 => '保存设备与页面的绑定关系参数错误' ,
9001033 => '门店ID不合法' ,
9001034 => '设备备注信息过长' ,
9001035 => '设备申请参数不合法' ,
9001036 => '查询起始值begin不合法' ,
];
/**
* 错误信息处理成中文
* @param $data 处理数据
*
* @return array|bool 处理完成的数据
*/
public function get($data)
{
if(!is_array($data) || !array_key_exists('errcode',$data))
{
return $data;
}
if(isset($this->error[$data['errcode']])){
//如果成功
if($data['errcode']==0){
return true;
}
//如果失败
return ['errcode'=>$data['errcode'],'errmsg'=>$this->error[$data['errcode']]];
}
//在错误属性找不到这个错误码
return ['errcode'=>'-2','errmsg'=>'未知错误'];
}
}
创建wechat文件夹并创建Wx.php工具类
<?php
namespace wx;
/**
* Created by PhpStorm.
* User: guobao
* Date: 2018/7/29
* Time: 下午7:00
*/
class Wx extends Error
{
public static $config = [];
//粉丝提交过来的信息
public $message;
//微信接口
public $apiUrl;
//获取access_token
public $access_token;
public function __construct($config = [])
{
if($config){
self::$config = $config;
}
$this->apiUrl = "https://api.weixin.qq.com";
$this->accessToken = $this->getAccessToken();
$this->message = $this->responseMsg();
}
//微信验证
public function valid(){
if(isset($_GET['signature']) && isset($_GET['timestamp']) && isset($_GET['nonce']) && isset($_GET['echostr'])){
$signature = $_GET['signature'];
$timestamp = $_GET['timestamp'];
$nonce = $_GET['nonce'];
$token = 'houdunwang';
$tmpArr = [ $token , $timestamp , $nonce ];
sort( $tmpArr , SORT_STRING );
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ) {
echo $_GET["echostr"];
exit;
} else {
return false;
}
}
}
//获取粉丝发送过来的消息
public function message(){
return $this->message;
}
//接收服务器发过来的数据
public function responseMsg()
{
$xml = file_get_contents('php://input');
//判断是否有数据
if( $xml ) {
return simplexml_load_string( $xml , 'SimpleXMLElement' , LIBXML_NOCDATA );
}
}
/**
* curl 请求
* @param $url 请求地址
* @param array $fields 请求数据
* @return string
*/
public function curl( $url , $fields = [ ] )
{
$ch = curl_init();
//设置我们的请求
curl_setopt( $ch , CURLOPT_URL , $url );
//数据返回后不要直接显示
curl_setopt( $ch , CURLOPT_RETURNTRANSFER , 1 );
//禁止证书校验
curl_setopt( $ch , CURLOPT_SSL_VERIFYPEER , false );
curl_setopt( $ch , CURLOPT_SSL_VERIFYHOST , false );
if( $fields ) {
curl_setopt( $ch , CURLOPT_TIMEOUT , 30 );//超时时间,超时请求自动终止
curl_setopt( $ch , CURLOPT_POST , 1 );//开启post发送
curl_setopt( $ch , CURLOPT_POSTFIELDS , $fields );//开启post发送
}
$data = '';
if( curl_exec( $ch ) ) {//如果发送成功
//获取数据
$data = curl_multi_getcontent( $ch );
}
//关闭连接
curl_close( $ch );
return $data;
}
//获取access_token
public function getAccessToken()
{
$url = $this->apiUrl."/cgi-bin/token?grant_type=client_credential&appid=".self::$config['appID']."&secret=".self::$config['appsecret'];
// exit($url);
$dir = __DIR__ . '/cache';
is_dir($dir) || mkdir($dir);
$file =$dir .'/token_'. md5(self::$config['appID'].self::$config['appsecret']). '.php';
// exit($file);
if(is_file($file) && filemtime($file)+7000>time()){
$data = include $file;
}else{
$data = $this->curl($url);
$data = json_decode($data,true);
if(isset($data['errcode'])){
return false;
}
file_put_contents($file,'<?php return '.var_export($data,true).' ?>');
}
//把access_token返回
return $this->access_token = $data['access_token'];
}
//获取临时票据
//jsapi_ticket是公众号用于调用微信JS接口的临时票据
public function getJsapi_ticket(){
$dir = __DIR__ . '/cache';
is_dir($dir) || mkdir($dir);
$file =$dir .'/ticket_'. md5(self::$config['appID'].self::$config['appsecret']). '.php';
// exit($file);
if(is_file($file) && filemtime($file)+7000>time()) {
$data = include $file;
// print_r($data);
}else{
$url = $this->apiUrl."/cgi-bin/ticket/getticket?access_token=".$this->access_token."&type=jsapi";
// print_r($url);
$data = json_decode($this->curl($url),true);
if($data['errcode'] !=0){
return false;
}
file_put_contents($file,'<?php return '.var_export($data,true).' ?>');
}
return $data['ticket'];
}
}
在wechat文件夹中创建core核心类文件夹,里面存放核心类
1.处理消息类
<?php
namespace wx\core;
use wx\Wx;
/**
* Created by PhpStorm.
* User: guobao
* Date: 2018/7/29
* Time: 下午7:34
*/
class Message extends Wx
{
//自动回复文本消息
public function autoText($content){
$xml = '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>';
$xml = sprintf($xml,$this->message->FromUserName,$this->message->ToUserName,time(),$content);
echo $xml;
}
//自动回复图片
public function autoImg($img){
$xml = '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA[%s]]></MediaId></Image></xml>';
$xml = sprintf($xml,$this->message->FromUserName,$this->message->ToUserName,time(),$img);
echo $xml;
}
//用户关注,如果新关注发送消息
public function isSubscribe(){
return $this->message->MsgType == 'event' && $this->message->Event == 'subscribe';
}
//取消关注
public function isUnsubscribe(){
return $this->message->MsgType == 'event' && $this->message->Event == 'unsubscribe';
}
}
2.菜单(创建按钮)
<?php
namespace wx\core;
use wx\Wx;
/**
* 按钮处理类
* Class Button
* @package wechat\build
*/
class Button extends Wx
{
/**
* 创建按钮
* @param $data json数据
*/
public function create($data)
{
//设置请求地址 获取access_token 的值
$url = $this->apiUrl . "/cgi-bin/menu/create?access_token=" . $this->access_token;
//使用curl请求
$res = json_decode($this->curl($url,$data),true);
return $this->get($res);
}
//自定义菜单查询接口
public function getButton(){
$url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=".$this->access_token;
$res = json_decode($this->curl($url),true);
return $this->get($res);
}
// 删除按钮方法
public function flush()
{
//http请求方式:GET
$url = $this->apiUrl . '/cgi-bin/menu/delete?access_token='.$this->access_token;
$res = json_decode($this->curl($url),true);
return $this->get($res);
}
}
3.微信jsSdk
<?php
/**
* Created by PhpStorm.
* User: guobao
* Date: 2018/7/30
* Time: 上午11:20
*/
namespace wx\core;
use wx\Wx;
class JsSdk extends Wx
{
//生成签名方法
public function makeSign(){
$noncestr = $this->makeStr();
$jsapi_ticket = $this->getJsapi_ticket();
// print_r($jsapi_ticket);
$timestamp = time();
$url= 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$arr = [
'noncestr=' . $noncestr,
'jsapi_ticket=' . $jsapi_ticket,
'timestamp=' . $timestamp,
'url=' . $url,
];
sort($arr,SORT_STRING);
$str = implode($arr,'&');
$sign = sha1($str);
//返回之前,组合需要使用的数据的数组
$array = [
'sign' => $sign,
'timestamp' => $timestamp,
'nonceStr' => $noncestr,
'appId' => 'wxceb8895e60442f79',
'url' => $url
];
//将数组返回去
return $array;
}
//生成随机字符串
public function makeStr(){
$seed = '1fsds33rddfsd4fsa6fs2sdsdd';
$str = '';
for ($i=0;$i<8;$i++){
$num = mt_rand(0,strlen($seed)-1);
$str .= $seed[$num];
}
return $str;
}
}
4.用户类
<?php
/**
* Created by PhpStorm.
* User: guobao
* Date: 2018/7/30
* Time: 上午9:13
*/
namespace wx\core;
use wx\Wx;
class User extends Wx
{
//创建标签
public function createTag($post){
$url = $this->apiUrl."/cgi-bin/tags/create?access_token=".$this->access_token;
$data = json_decode($this->curl($url,$post),true);
return $this->get($data);
}
//获取已创建标签
public function getTag(){
$url = $this->apiUrl."/cgi-bin/tags/get?access_token=".$this->access_token;
$data = json_decode($this->curl($url),true);
return $this->get($data);
}
//获取用户备注名
public function setName($post){
$url = $this->apiUrl."/cgi-bin/user/info/updateremark?access_token=".$this->access_token;
$data = json_decode($this->curl($url,$post),true);
return $this->get($data);
}
//获取用户基本信息
public function getUserInfo($openid,$lang = 'zh_CN'){
$url = $this->apiUrl."/cgi-bin/user/info?access_token=".$this->access_token."&openid=".$openid."&lang=zh_CN".$lang;
// exit($url);
$data = json_decode($this->curl($url),true);
return $this->get($data);
}
//批量获取用户基本信息
public function userInfoList($post,$lang = 'zh_CN'){
$url = $this->apiUrl."/cgi-bin/user/info/batchget?access_token=".$this->access_token."&openid=".$openid."&lang=zh_CN".$lang;
//重组数组
$users = [];
foreach($post as $v){
$users['user_list'][] = [
'openid' => $v,
'lang' =>$lang,
];
}
$users = json_encode($users,true);
$data = json_decode($this->curl($url,$users),true);
return $this->get($data);
}
//获取用户列表
public function getUserLists($openid){
$url = $this->apiUrl."/cgi-bin/user/get?access_token=".$this->access_token."&next_openid=".$openid;
$data = json_decode($this->curl($url),true);
return $this->get($data);
}
}