menu.php
菜单配置
<?php
return <<<EOL
{
"button":[
{
"type":"click",
"name":"首页",
"key":"index001"
},
{
"name":"最新活动",
"sub_button":[
{
"type":"view",
"name":"搜索",
"url":"http://www.soso.com/"
},
{
"type":"click",
"name":"客服",
"key":"kefu001"
},
{
"type": "pic_sysphoto",
"name": "系统拍照发图",
"key": "photo001",
"sub_button": [ ]
},
{
"name": "发送位置",
"type": "location_select",
"key": "rselfmenu_2_0"
}]
},
{
"type":"view",
"name":"个人中心",
"url":"http://www.baidu.com/"
}
]
}
EOL;
主动模式.php
<?php
/**
* 微信主动模式
*/
// $wx = new Wxz();
// echo $wx->signature();
// echo $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
// // $menuList = include './menu.php';
// echo "<img src='".$wx->createQ(0,10)."' />";
// # echo $wx->createMenu($menuList);
class Wxz
{
const APPID = 'xxxx';
const APPS = 'xxxx';
/**
* 得到access_token 全局唯一
*/
// public function getAToken() {
// $cacheFile = self::APPID.'_cache.log';
// // 判断文件是否存在,不存在表示无缓存
// // 存在判断修改时间是否过了有效期,没过,不发起网络请求
// if(is_file($cacheFile) && filemtime($cacheFile)+7000 > time()){
// # echo '缓存<hr>';
// return file_get_contents($cacheFile);
// }
// // 第一次或缓存过期
// $surl = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s';
// $url = sprintf($surl,self::APPID,self::APPS);
// // 发起get请求
// $json = $this->http_req($url);
// $arr = json_decode($json, true);
// $at = $arr['access_token'];
// // 写入缓存
// file_put_contents($cacheFile,$at);
// // 返回数据
// # echo '请求<hr>';
// return $at;
// }
/**
* 上传素材
*/
public function uploadM(string $path, string $type = 'image', int $is_forever = 0)
{
if ($is_forever) {
// 永久
$surl = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s";
} else {
// 临时
$surl = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=%s&type=%s";
}
// 上传素材到微信公众平台
$url = sprintf($surl, $this->getATokenMem(), $type);
$arr = $this->uploadF($url, $path);
// $arr = json_decode($json,true);
// null合并
return $arr['media_id'] ?? '';
}
/**
* post 方式上传文件
*/
public function uploadF(string $url, string $filepath)
{
/* 使用exec函数 */
$command = 'curl -F media=@' . $filepath . ' "' . $url . '"';
$retval = array();
exec($command, $retval, $status);
$params = array();
$params = json_decode($retval[0], true);
if ($status != 0) {
$params = array(
'errcode' => '-100',
'errmsg' => '公众号服务出错,请联系管理员',
);
}
return $params;
}
/**
* 获取缓存的access_token 使用memcache
*/
public function getATokenMem()
{
$cacheKey = self::APPID . '_key';
$mem = new Memcache();
$mem->addServer('localhost', 11211);
//有缓存 读缓存
if (false != ($at = $mem->get($cacheKey))) {
# echo '缓存<hr>';
// # echo $at;
return $at;
}
// 判断文件是否存在,不存在表示无缓存
// 存在判断修改时间是否过了有效期,没过,不发起网络请求
// 第一次或缓存过期
$surl = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s';
$url = sprintf($surl, self::APPID, self::APPS);
// 发起get请求
$json = $this->http_req($url);
$arr = json_decode($json, true);
$at = $arr['access_token'];
// 写入缓存
$mem->set($cacheKey, $at, MEMCACHE_COMPRESSED, 7000);
// 返回数据
# echo '请求<hr>';
// # echo $at;
return $at;
}
/**
* 发起请求
* @param string $url
* @param string|array $ret 请求体
*
*/
private function http_req($url, $ret = '')
{
// 初始化
$ch = curl_init();
// 相关设置
curl_setopt($ch, CURLOPT_URL, $url);
// 不要请求头
curl_setopt($ch, CURLOPT_HEADER, 0);
// 请求结果不直接输出,而是字符串返回
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
# 设置请求超时时间 s
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
# 设置浏览器型号
curl_setopt($ch, CURLOPT_HEADER, 'MSIE001');
# 证书不检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
# 设置为post请求
if ($ret != '') {
// 开启post
curl_setopt($ch, CURLOPT_POST, 1);
// post请求数据
curl_setopt($ch, CURLOPT_POSTFIELDS, $ret);
}
// 发起请求
$data = curl_exec($ch);
// 有无发送异常
if (curl_errno($ch) > 0) {
// 把错误发送给客户端
# echo curl_error($ch);
$data = '';
}
// 关闭请求
curl_close($ch);
return $data;
}
/**
* 删除菜单
*/
public function delMenu()
{
$url = 'https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=' . $this->getATokenMem();
// 发送post请求
// 获取返回json结果
$json = $this->http_req($url);
return $json;
}
/**
* 创建菜单
*/
public function createMenu($menu)
{
if (is_array($menu)) {
$data = json_encode($menu, 256); // 防止乱码
} else {
$data = $menu;
}
// # echo $data;
$url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token=' . $this->getATokenMem();
// 发送post请求
// 获取返回json结果
$json = $this->http_req($url, $data);
#$arr = json_decode($json,true);
return $json;
}
/**
* 客服消息
*/
public function kefuMsg($openid, $msg) {
$url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' . $this->getATokenMem();
$data = '{
"touser":"'.$openid.'",
"msgtype":"text",
"text":
{
"content":"'.$msg.'"
}
}
';
$json = $this->http_req($url, $data);
return $json;
}
/**
* 生成场景二维码
* @param int $flag 0 临时
*/
public function createQ(int $flag=0, int $id=5) {
// 获取ticket
$url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=' . $this->getATokenMem();
if(0==$flag) {
// 临时
$data = '{"expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": '.$id.'}}}';
}else {
$data = '{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": '.$id.'}}}';
}
// 得到ticket
$json = $this->http_req($url, $data);
# json转数组
$arr = json_decode($json, true);
$ticket = $arr['ticket'];
// 用tciket换二维码
# TICKET记得进行UrlEncode
$url = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='.urlencode($ticket);
# 发起get请求
$img = $this->http_req($url);
// return $img;
// 写入文件
file_put_contents('qrcode.jpg',$img);
return 'qrcode.jpg';
}
/**
* 获得jsapi_ticket
*/
public function getTicket() {
$url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token='. $this->getATokenMem();
$json = $this->http_req($url);
$arr = json_decode($json, true);
return $arr['ticket'];
}
/**
* 随机字符串
*/
private function nocestr(int $len=16){
$str= 'dadadsadfsaffdsgrg4d5g4d5g4f2v12';
$str = md5($str);
$str = str_shuffle($str);
return substr($str,0,$len);
}
/**
* 获取当前url
*/
private function getCUrl() {
return $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
}
/**
* jssdk使用的签名
*/
public function signature() {
$ticket = $this->getTicket();
$nocestr = $this->nocestr();
$time = time();
$url = $this->getCUrl();
$str = 'jsapi_ticket=%s&noncestr=%s×tamp=%s&url=%s';
$str = sprintf($str,$ticket,$nocestr,$time,$url);
$signature = sha1($str);
return [
'appid' => self::APPID,
'ticket' => $ticket,
'nocestr' => $nocestr,
'time' => $time,
'url' => $url,
'signature' => $signature
];
}
}