Correction status:qualified
Teacher's comments:
<?php /** * Created by PhpStorm. * User: Administrator * Date: 2018/6/1 0001 * Time: 上午 9:52 */ namespace app\index\controller; use think\Controller; use think\facade\Request; //注意驼峰规则命名的控制器在url中访问中间是要加 _ 下划线的 略坑 不知道为什么这么设计 class Weixin extends Controller { public function __construct() { parent::__construct(); $this->model = model('WeixinModel');//这块控制器名字写错了 难怪出不来。。。。 } //验证签名 public function check() { $valid = $this->model->checkToken(); if (is_bool($valid) && !$valid) { exit('signature error'); } $xmldata = file_get_contents("php://input"); file_put_contents('D://location0.txt', $xmldata); file_put_contents("c:\xmldata.txt", $xmldata); $postObj = simplexml_load_string($xmldata, 'SimpleXMLElement', LIBXML_NOCDATA); $data = (array)$postObj; // 事件推送 if (isset($data['MsgType'])) { switch ($data['MsgType']) { case "event": switch ($data['Event']) { case 'subscribe': $this->model->subscribe($data); break; case 'unsubscribe': $this->model->unsubscribe($data); break; case 'LOCATION': file_put_contents('D://location.txt', var_export($data, true)); if (isset($data['Latitude'])) { $this->model->locationinfo($data); exit('success'); } break; } break; case "text": // file_put_contents('C://text0.txt',$xmldata); // file_put_contents('C://text12.txt',$data['Content']); $this->model->respontext($data); exit('success'); break; case "image": $this->model->respontextimg($data); exit('success'); break; } } exit(input('get.echostr')); } //获取access_token public function access_token() { $res = $this->model->getAccessToken(); if (is_bool($res) && !$res) { return "token获取失败"; } return $res; } public function set_bottom_menu() { $res = $this->model->SetBottomMenu(); exit($res); } //认证获取code public function auth() { $appid = config('app.appid'); $redirect = 'http://cf449e3d.ngrok.io/index.php/index/weixin/userinfo'; $url_code = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' . $appid . '&redirect_uri=' . urlEncode($redirect) . '&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect'; file_put_contents("c:\url_code.txt", $url_code); header('Location:' . $url_code); } //认证获取code之后 这里获取返回code 并验证网页授权 public function userinfo() { // 获取code // $code = input('get.code'); $code = Request::get('code'); dump($code, true, "code:"); file_put_contents("c:\b.txt", $code); // 第二步:通过code换取网页授权access_token $res = $this->model->auth_access_token($code); $auth_access_token = $res['access_token']; dump($auth_access_token, true, "auth_access_token:"); $openid = $res['openid']; // 第三步:拉取用户信息(需scope为 snsapi_userinfo) $userinfo = $this->model->get_userinfo($auth_access_token, $openid); dump($userinfo); $this->model->setnickname($openid, $userinfo); $this->view->assign('openid', $userinfo['openid']); $this->view->assign('userinfo', $userinfo); return $this->view->fetch(); } public function get_location() { $opts = array('http' => array('header' => "User-Agent:MyAgent/1.0\r\n")); $context = stream_context_create($opts); // $res = file_get_contents('http://cf449e3d.ngrok.io/index.php/index/weixin/location', false, $context); // $res = file_get_contents("http://e45191e0.ngrok.io/index.php/index/weixin/location"); $jsonData = file_get_contents("http://cf449e3d.ngrok.io/index.php/index/weixin/location",false,$context); exit($jsonData); } public function location() { $data['appid'] = config('app.appid'); $data['timestamp'] = time(); $data['nonceStr'] = md5(time() . rand(1, 999)); //获取本地access_token(注意这个跟web授权的access_token不是同一个); $res = $this->model->getAccessToken(); if (is_bool($res)) { exit("获取token失败"); } $access_token = $res; $jsapi_ticket = $this->model->jsapi_ticket($access_token, true); $data['$jsapi_ticket'] = $jsapi_ticket; if (is_bool($jsapi_ticket)) { return utf8_encode("获取jsapi_ticket失败"); } // 2、构造签名字符串 $params['noncestr'] = $data['nonceStr']; // $params['jsapi_ticket'] = $jsapi_ticket; $params['jsapi_ticket'] = $data['$jsapi_ticket']; $params['timestamp'] = $data['timestamp']; $params['url'] = 'http://cf449e3d.ngrok.io/index.php/index/weixin/get_location'; ksort($params); $str = urldecode(http_build_query($params)); // 防止url字符转义 // 3、生成签名 $data['signature'] = sha1($str); // $this->view->assign("data", $data); // $this->view->assign("jsapi_ticket", $data['$jsapi_ticket']); $this->view->assign("appid", $data['appid']); $this->view->assign("timestamp", $data['timestamp']); $this->view->assign("noncestr", $data['nonceStr']); $this->view->assign("signature", $data['signature']); return $this->view->fetch(); } }
点击 "运行实例" 按钮查看在线实例
<?php /** * Created by PhpStorm. * User: Administrator * Date: 2018/6/1 0001 * Time: 上午 9:52 */ namespace app\index\model; use think\facade\Request; use think\facade\Config; use think\Model; use think\Facade\Cache; class WeixinModel extends Model { protected $table = 'user'; protected $pk = 'uid'; public function checkToken() { // $signature = input('get.signature'); // $timestamp = input('get.timestamp'); // $nonce = input('get.nonce'); // $echostr = input('get.echostr'); // $Token = config('app.token'); $signature = Request::param('signature'); $timestamp = Request::param('timestamp'); $nonce = Request::param('nonce'); $echostr = Request::param('echostr'); $Token = Config::get('app.token'); // file_put_contents("E:\php\phpStudy_tools\myphp_www\PHPTutorial\WWW\php\WeiXin\a.txt","signature ".$signature." timestamp ".$timestamp." nonce ".$nonce." echostr ".$echostr); $tmpArr = array($timestamp, $nonce, $Token); sort($tmpArr, SORT_STRING); $tmpStr = implode($tmpArr); $tmpStr = sha1($tmpStr); if ($tmpStr != $signature) { return false; } return true; } // 关注 public function subscribe($data) { file_put_contents("C:/guanzhu.txt", var_export($data, true)); // 检查用户是否已存在 // $user = Db::name('user')->where(array('openid'=>$data['FromUserName']))->find(); $user = WeixinModel::where('openid', $data['FromUserName'])->find(); if ($user == null) { $dataUser = [ 'openid' => $data['FromUserName'], 'sub_status' => 1, 'add_time' => time() ]; WeixinModel::insertGetId($dataUser); } else { $dataUser = [ 'openid' => $data['FromUserName'], 'sub_status' => 1, 'add_time' => time() ]; WeixinModel::update($dataUser, function ($query) use ($data) { $query->where("openid", $data['FromUserName']); }); } } public function setnickname($openid, $userinfo) { $user = WeixinModel::where('openid', $openid)->find(); if ($user != null) { $dataUser = [ 'nickname' => $userinfo['nickname'], ]; WeixinModel::update($dataUser, function ($query) use ($openid) { $query->where("openid", $openid); }); } } // 取消关注 public function unsubscribe($data) { file_put_contents("C:/cacle.txt", var_export($data, true)); $user = WeixinModel::where('openid', $data['FromUserName'])->find(); if ($user == null) { $dataUser = [ 'openid' => $data['FromUserName'], 'sub_status' => 1, 'add_time' => time() ]; WeixinModel::insertGetId($dataUser); } else { $dataUser = [ 'openid' => $data['FromUserName'], 'sub_status' => 0, 'add_time' => time() ]; WeixinModel::update($dataUser, function ($query) use ($data) { $query->where("openid", $data['FromUserName']); }); } } public function getAccessToken($iscache = true) { $key = 'access_token'; if (!$iscache) { Cache::rm($key); } $data = Cache::get($key); if ($data && $iscache) { return $data; } $appid = Config::get('app.appid'); $appsecret = config('app.appsecret'); $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appid . '&secret=' . $appsecret; $res = http_get($url); $res = json_decode($res, true); if (!isset($res['access_token'])) { return false;/*'获取token失败'$res['errmsg']*/ } Cache::set($key, $res['access_token'], ($res['expires_in'] - 100)); return $res['access_token']; } // 网页授权access_token public function auth_access_token($code) { $appid = config('app.appid'); $appsecret = config('app.appsecret'); $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $appid . '&secret=' . $appsecret . '&code=' . $code . '&grant_type=authorization_code'; $res = http_get($url); $res = json_decode($res, true); if (!isset($res['access_token'])) { return false; } return $res; } // 拉取用户信息 public function get_userinfo($auth_access_token, $openid) { $url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $auth_access_token . '&openid=' . $openid . '&lang=zh_CN'; $res = http_get($url); $res = json_decode($res, true); return $res; } public function locationinfo($data) { $user = WeixinModel::where('openid', $data['FromUserName'])->find(); if ($user != null) { $dataUser = [ 'lat' => $data['Latitude'], 'lng' => $data['Longitude'] ]; WeixinModel::update($dataUser, function ($query) use ($data) { $query->where("openid", $data['FromUserName']); }); } } public function jsapi_ticket($access_token,$iscache = true) { $key = 'jsapi_ticket'; if (!$iscache){ Cache::rm($key); } $data = Cache::get($key); if($data && $iscache){ return $data; } if (!isset($access_token)) { return false; } $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" . $access_token . "&type=jsapi"; $res = http_Get($url); $res = json_decode($res, true); if (!isset($res['ticket'])) { return false; } Cache::set($key,$res['ticket'],($res['expires_in']-100)); return $res['ticket']; } /** * 被动回复文本消息 * @param $toUser 接收方帐号(收到的OpenID) * @param $fromUser 开发者微信号 * @param $CreateTime 消息创建时间 (整型) * @param $text text * @param $respontext 回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示) */ public function respontext($data) { // file_put_contents('C://text1.txt',"1"); $respon = '<xml> <ToUserName>' . $data['FromUserName'] . '</ToUserName> <FromUserName>' . $data['ToUserName'] . '</FromUserName> <CreateTime>' . time() . '</CreateTime> <MsgType>text</MsgType> <Content>' . $data['Content'] . '</Content></xml>'; // file_put_contents('C://text2.txt',$respon); exit($respon); } /** * 被动回复图文消息 * @param $data */ public function respontextimg($data) { $respon = '<xml><ToUserName>'.$data['FromUserName'].'</ToUserName><FromUserName>'.$data['ToUserName'].'</FromUserName><CreateTime>'.time().'</CreateTime><MsgType>news</MsgType><ArticleCount>2</ArticleCount><Articles>'; for ($i = 0;$i<2;$i++){ $respon.='<item><Title>测试title>'.$i.'</Title> <Description>描述啊'.$i.'</Description><PicUrl>https://weixin.qq.com/cgi-bin/readtemplate?t=mac&lang=zh_CN</PicUrl><Url>https://weixin.qq.com</Url></item>'; } $respon.='</Articles></xml>'; exit($respon); } public function SetBottomMenu() { $access_token = self::getAccessToken(); $url = ' https://api.weixin.qq.com/cgi-bin/menu/create?access_token=' . $access_token; $data = '{ "button":[ { "type":"view", "name":"首页", "url":"http://m.php.cn/" }, { "type":"view", "name":"视频", "url":"http://m.php.cn/" }, { "name":"接口DEM0", "sub_button":[ { "type":"view", "name":"用户信息", "url":"http://cf449e3d.ngrok.io/index.php/index/weixin/auth" }, { "type":"view", "name":"用户地理位置", "url":"http://cf449e3d.ngrok.io/index.php/index/weixin/get_location" }] }] }'; $res = http_Post($url, $data); return $res; } }
点击 "运行实例" 按钮查看在线实例