Receive.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <?php
  2. /*
  3. |--------------------------------------------------------------------------
  4. | receive.php 用于接收微信发过来的信息
  5. |--------------------------------------------------------------------------
  6. */
  7. namespace Component\Service;
  8. use Dever;
  9. use Main\Lib\Wechat;
  10. class Receive
  11. {
  12. const TYPE = 5;
  13. /**
  14. * wechat
  15. *
  16. * @var Wechat
  17. */
  18. private $wechat;
  19. /**
  20. * result
  21. *
  22. * @var array
  23. */
  24. private $result;
  25. /**
  26. * output
  27. *
  28. * @var string
  29. */
  30. private $output;
  31. /**
  32. * 构造函数 初始化
  33. *
  34. * @return mixed
  35. */
  36. public function __construct()
  37. {
  38. $this->wechat = new Wechat(self::TYPE);
  39. }
  40. /**
  41. * 业务推送接口 微信服务器会将所有请求都推送到这里
  42. *
  43. * @return mixed
  44. */
  45. public function main()
  46. {
  47. $this->output = '';
  48. # 获取微信消息
  49. $this->request();
  50. # 对消息进行验证,并根据类型得到本平台的配置数据
  51. //$this->response();
  52. # 输出
  53. $this->output();
  54. }
  55. /**
  56. * 输出
  57. *
  58. * @return mixed
  59. */
  60. private function output()
  61. {
  62. if (!$this->output) {
  63. $this->output = 'success';
  64. }
  65. echo $this->output;die;
  66. }
  67. /**
  68. * 据类型得到本平台的配置数据
  69. *
  70. * @return mixed
  71. */
  72. private function response()
  73. {
  74. if ($this->output) {
  75. return;
  76. }
  77. if ($this->result && isset($this->result['add_type'])) {
  78. if (isset($this->result['subscribe'])) {
  79. if ($this->result['subscribe'] == true) {
  80. # 订阅成功 发送消息
  81. $this->msg('msg1');
  82. # 发送消息之后,往用户表更新信息
  83. $this->user();
  84. $this->setSubscribe(1);
  85. }
  86. if ($this->result['subscribe'] == false) {
  87. # 取消订阅 不发送消息
  88. //$this->msg('msg1');
  89. # 改变当前用户的订阅状态
  90. $this->setSubscribe(2);
  91. }
  92. } elseif (isset($this->result['add_content'][0]['Content'])) {
  93. $this->match($this->result['add_content'][0]['Content']);
  94. } else {
  95. # 如果没有匹配到,则直接返回默认回复消息
  96. $this->msg('msg2');
  97. }
  98. }
  99. }
  100. /**
  101. * 获取微信发送的内容
  102. *
  103. * @return mixed
  104. */
  105. private function request()
  106. {
  107. //$post = $_GET ? $_GET : $_POST;
  108. $post = file_get_contents('php://input');
  109. /*
  110. $post = ' <xml>
  111. <ToUserName><![CDATA[toUser]]></ToUserName>
  112. <FromUserName><![CDATA[ow29VvzICifpOTq_9EDGT3AhYpqg]]></FromUserName>
  113. <CreateTime>1442067297</CreateTime>
  114. <MsgType><![CDATA[text]]></MsgType>
  115. <Content><![CDATA[dfd]]></Content>
  116. <MsgId>1311112322222222</MsgId>
  117. </xml>';
  118. /*
  119. $post = '<xml>
  120. <ToUserName><![CDATA[toUser]]></ToUserName>
  121. <FromUserName><![CDATA[FromUser]]></FromUserName>
  122. <CreateTime>123456789</CreateTime>
  123. <MsgType><![CDATA[event]]></MsgType>
  124. <Event><![CDATA[subscribe]]></Event>
  125. </xml>';
  126. $post = ' <xml>
  127. <ToUserName><![CDATA[toUser]]></ToUserName>
  128. <FromUserName><![CDATA[ow29VvzICifpOTq_9EDGT3AhYpqg]]></FromUserName>
  129. <CreateTime>1442067297</CreateTime>
  130. <MsgType><![CDATA[image]]></MsgType>
  131. <PicUrl><![CDATA[http://mmbiz.qpic.cn/mmbiz/OxUBpiaYgpHiaDaiccrsX3MrFEVtjIfEAZk8zoJDZ4gXWWW2CIFic6Dicqndu23wMgA4Icg3yE4SRZg6L5jqanu9kvQ/0]]></PicUrl>
  132. <MediaId><![CDATA[media_id]]></MediaId>
  133. <MsgId>111</MsgId>
  134. </xml>';
  135. $post = '<xml>
  136. <ToUserName><![CDATA[toUser]]></ToUserName>
  137. <FromUserName><![CDATA[ow29VvzICifpOTq_9EDGT3AhYpqg]]></FromUserName>
  138. <CreateTime>1442067297</CreateTime>
  139. <MsgType><![CDATA[voice]]></MsgType>
  140. <MediaId><![CDATA[media_id]]></MediaId>
  141. <Format><![CDATA[Format]]></Format>
  142. <MsgId>23123213</MsgId>
  143. </xml>';
  144. $post = '<xml>
  145. <ToUserName><![CDATA[toUser]]></ToUserName>
  146. <FromUserName><![CDATA[FromUser]]></FromUserName>
  147. <CreateTime>123456789</CreateTime>
  148. <MsgType><![CDATA[event]]></MsgType>
  149. <Event><![CDATA[CLICK]]></Event>
  150. <EventKey><![CDATA[EVENTKEY]]></EventKey>
  151. </xml>';
  152. */
  153. Dever::log(time());
  154. if (!empty($post)) {
  155. $post = json_encode($post);
  156. Dever::log($post);
  157. return;
  158. libxml_disable_entity_loader(true);
  159. $result = (array) simplexml_load_string($post, 'SimpleXMLElement', LIBXML_NOCDATA);
  160. $this->handle($result);
  161. } else {
  162. return false;
  163. }
  164. }
  165. /**
  166. * 对微信的内容做处理,得到最终结果
  167. *
  168. * @return mixed
  169. */
  170. private function handle($result)
  171. {
  172. return;
  173. $config = array
  174. (
  175. 'AppId' => 'add_appid',
  176. 'CreateTime' => 'add_create_date',
  177. 'InfoType' => 'add_type',
  178. 'ComponentVerifyTicket' => 'add_ticket',
  179. );
  180. foreach ($config as $k => $v) {
  181. $this->result($k, $v, $result);
  182. }
  183. # 事件处理
  184. $this->event();
  185. $this->save();
  186. }
  187. /**
  188. * 事件处理
  189. *
  190. * @return mixed
  191. */
  192. private function event()
  193. {
  194. if ($this->result['add_type'] == 'component_verify_ticket') {
  195. }
  196. }
  197. /**
  198. * 入库
  199. *
  200. * @return mixed
  201. */
  202. private function save()
  203. {
  204. $this->result['add_info'] = is_array($this->result['add_info']) ? implode(',', $this->result['add_info']) : $this->result['add_info'];
  205. $this->result['add_site'] = $this->core->site();
  206. # 入库 使用mid排重
  207. $info = array();
  208. if (isset($this->result['add_mid'])) {
  209. $info = Dever::load('weixin/usermsg-getOne', array('where_mid' => $this->result['add_mid'], 'where_site' => $this->result['add_site']));
  210. $this->result['id'] = $info['id'];
  211. }
  212. if (!$info) {
  213. $this->result['id'] = Dever::load('weixin/usermsg-insert', $this->result);
  214. # 记录点对点聊天记录 暂时不记录了
  215. /*
  216. if($this->result['add_type'] == 'text')
  217. {
  218. $update['add_state'] = 1;
  219. $update['add_openid'] = $this->result['add_from'];
  220. $update['add_usermsg_id'] = $this->result['id'];
  221. $update['add_account'] = -1;
  222. $update['add_type'] = $this->result['add_type'];
  223. $update['add_info'] = Dever::load('weixin/user.msg', $this->result['id']);
  224. Dever::load('weixin/usermsg_log-insert', $update);
  225. }
  226. */
  227. }
  228. }
  229. /**
  230. * 得到最终结果
  231. *
  232. * @return mixed
  233. */
  234. private function result($key, $index, $result, $name = '')
  235. {
  236. if (isset($result[$key])) {
  237. $value = trim($result[$key]);
  238. if ($index == 'add_type') {
  239. $this->type($value, $result);
  240. }
  241. if ($index == 'add_content') {
  242. //$key = $name ? $name : $key;
  243. $this->result[$index][0][$key] = $value;
  244. $this->info($key, $value);
  245. } elseif ($index == 'add_ctime') {
  246. $this->result[$index] = $value ? $value : time();
  247. } else {
  248. $this->result[$index] = $value;
  249. }
  250. }
  251. }
  252. /**
  253. * 根据状态得到用户发送的具体内容,为了响应及时,这里不做解析。
  254. *
  255. * @return mixed
  256. */
  257. private function info($key, $value)
  258. {
  259. $this->result['add_info'][] = $value;
  260. }
  261. /**
  262. * 得到type的值
  263. *
  264. * @return mixed
  265. */
  266. private function type($index, $result)
  267. {
  268. $type = $this->config($index);
  269. if (is_array($type)) {
  270. foreach ($type as $k => $v) {
  271. if (is_numeric($k)) {
  272. $k = $v;
  273. }
  274. $this->result($k, 'add_content', $result, $v);
  275. }
  276. } else {
  277. $this->result($type, 'add_content', $result);
  278. }
  279. }
  280. /**
  281. * 得到对应关系
  282. *
  283. * @return mixed
  284. */
  285. private function keywords($type)
  286. {
  287. # 根据keywords的type设定来设置对应关系
  288. $config = array
  289. (
  290. 1 => 'text',
  291. 2 => 'news',
  292. //3 => 'news',
  293. 4 => 'voice',
  294. 5 => 'video',
  295. 6 => 'image',
  296. );
  297. if (!isset($config[$type])) {
  298. return false;
  299. }
  300. $this->result['type'] = $config[$type];
  301. return $config[$type];
  302. }
  303. /**
  304. * 配置type类型
  305. *
  306. * @return mixed
  307. */
  308. private function config($key, $type = 'get')
  309. {
  310. $config = array
  311. (
  312. # 文本
  313. 'text' => array
  314. (
  315. # 设置获取的key 应答
  316. 'get' => 'Content',
  317. # 设置赋值的key 回复
  318. 'set' => 'Content',
  319. ),
  320. # 图片
  321. 'image' => array
  322. (
  323. 'get' => array('PicUrl', 'MediaId'),
  324. 'set' => array
  325. (
  326. 'Image' => array('MediaId' => 'pic')
  327. ),
  328. ),
  329. # 语音
  330. 'voice' => array
  331. (
  332. 'get' => array('MediaId', 'Format'),
  333. 'set' => array
  334. (
  335. 'Voice' => array('MediaId' => 'mp3')
  336. ),
  337. ),
  338. # 视频
  339. 'video' => array
  340. (
  341. 'get' => array('MediaId', 'ThumbMediaId'),
  342. 'set' => array
  343. (
  344. 'Voice' => array('MediaId' => 'mp4', 'Title' => 'title', 'Description' => 'info')
  345. ),
  346. ),
  347. # 小视频
  348. 'shortvideo' => array
  349. (
  350. 'get' => array('MediaId', 'ThumbMediaId'),
  351. 'set' => false,
  352. ),
  353. # 地理位置
  354. 'location' => array
  355. (
  356. 'get' => array('Location_X', 'Location_Y', 'Scale', 'Label'),
  357. 'set' => false,
  358. ),
  359. # 链接消息
  360. 'link' => array
  361. (
  362. 'get' => array('Title', 'Description', 'Url', 'Label'),
  363. 'set' => false,
  364. ),
  365. # 单图文消息
  366. 'new' => array
  367. (
  368. 'get' => false,
  369. 'set' => array
  370. (
  371. 'ArticleCount' => 1,
  372. 'Articles' => array
  373. (
  374. 'item' => array('Title' => 'title', 'Description' => 'info', 'PicUrl' => 'pic', 'Url' => 'link')
  375. )
  376. ),
  377. ),
  378. # 多图文消息
  379. 'news' => array
  380. (
  381. 'get' => false,
  382. 'set' => array
  383. (
  384. 'ArticleCount' => 'total',
  385. 'Articles' => array
  386. (
  387. 'item' => array('Title' => 'title', 'Description' => 'info', 'PicUrl' => 'pic', 'Url' => 'link')
  388. )
  389. ),
  390. ),
  391. # 音乐消息
  392. 'music' => array
  393. (
  394. 'get' => false,
  395. 'set' => false,
  396. ),
  397. # 事件消息,所有事件返回的字段都在此做说明
  398. 'event' => array
  399. (
  400. 'get' => array
  401. (
  402. 'Event' => '事件',
  403. 'EventKey' => '事件ID',
  404. 'Latitude' => '纬度',
  405. 'Longitude' => '经度',
  406. 'Precision' => '精度',
  407. 'Ticket' => '二维码',
  408. 'MsgID' => '消息ID',
  409. 'Status' => '状态',
  410. 'TotalCount' => '粉丝数',
  411. 'FilterCount' => '过滤数',
  412. 'SentCount' => '成功数',
  413. 'ErrorCount' => '失败数',
  414. ),
  415. 'set' => false,
  416. ),
  417. );
  418. return $config[$key][$type];
  419. }
  420. /**
  421. * 获取当前时间
  422. *
  423. * @return mixed
  424. */
  425. private function time()
  426. {
  427. return time();
  428. }
  429. /**
  430. * 拼装xml相应代码
  431. *
  432. * @return mixed
  433. */
  434. private function xml($content)
  435. {
  436. $xml = "<xml>\r\n"
  437. .$this->tag('ToUserName', $this->result['add_from']) . "\r\n"
  438. .$this->tag('FromUserName', $this->result['add_to']) . "\r\n"
  439. .$this->tag('CreateTime', $this->time()) . "\r\n"
  440. .$this->tag('MsgType', $this->result['type']) . "\r\n"
  441. .$content . "\r\n"
  442. .'</xml>';
  443. return $xml;
  444. }
  445. /**
  446. * 生成tag
  447. *
  448. * @return mixed
  449. */
  450. private function tag($tag, $value = '')
  451. {
  452. if (!is_numeric($value) && strpos($value, '<') === false) {
  453. $value = '<![CDATA['.$value.']]>';
  454. }
  455. return '<'.$tag.'>'.$value.'</'.$tag.'>';
  456. }
  457. }