-
Notifications
You must be signed in to change notification settings - Fork 0
/
wechatcommon.php
2534 lines (2317 loc) · 100 KB
/
wechatcommon.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?php
/**
* 微动微信接口基础类。
* 注意:该类不包括微信支付部分,微信支付分为第二版和第三版,放在WeChatPay接口部分。
* 微信支付类也已经经过微动重构,适合平台级支付。
* @author 赵臣升、万路康。
* CreateTime:2014/05/20.
* LatestModify:2015/04/19.
* ModifyFor:增加AES加密,丰富类功能。
* 特别注意:该类是平台级的企业用户接口类。
*/
class WeactWechat {
/**
* ==========常量微动/微信接口Web Service接口地址区域==========
*/
/**
* 获取微信开发者access_token的地址。
* @var String WECHAT_TOKEN
*/
const WECHAT_TOKEN = "https://api.weixin.qq.com/cgi-bin/token";
/**
* 微动平台微信token中控系统请求地址。
* @var String WECHAT_TOKEN_CENTRAL_SYSTEM
*/
const WECHAT_TOKEN_CENTRAL_SYSTEM = "http://www.we-act.cn/weact/Interface/ExportWeChat/getWeChatToken";
/**
* 微动平台全网发布token地址
* @var String OPEN_TOKEN_CENTRAL_SYSTEM
*/
const OPEN_TOKEN_CENTRAL_SYSTEM = "http://www.we-act.cn/weact/Interface/ExportWeChat/getOpenToken";
/**
* 微信平台服务器地址列表。
* @var String WECHAT_SERVER_IP
*/
const WECHAT_SERVER_IP = "https://api.weixin.qq.com/cgi-bin/getcallbackip";
/**
* 主动发送客服消息接口地址。
* @var String SEND_CUSTOMER_SERVICE_MESSAGE
*/
const SEND_CUSTOMER_SERVICE_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/custom/send";
/**
* ==========微信模板消息接口地址区域==========
*/
/**
* 为模板消息设置企业所属行业接口地址。
* @var String TEMPLATE_SET_INDUSTRY
*/
const TEMPLATE_SET_INDUSTRY = "https://api.weixin.qq.com/cgi-bin/template/api_set_industry";
/**
* 通过API接口添加模板消息模板接口地址。
* @var String API_ADD_TEMPLATE
*/
const API_ADD_TEMPLATE = "https://api.weixin.qq.com/cgi-bin/template/api_add_template";
/**
* 发送企业模板消息接口地址。
* @var String SEND_TEMPLATE
*/
const SEND_TEMPLATE = "https://api.weixin.qq.com/cgi-bin/message/template/send";
/**
* ==========微信素材管理接口地址区域==========
* 本区域接口共8个,分别为:
* 1、新增临时素材;2、获取临时素材;3、新增永久素材;4、获取永久素材;
* 5、删除永久素材;6、修改永久图文素材;7、获取素材总数;8、获取素材列表。
*/
/**
* 向微信平台上传多媒体接口地址。
* @var String UPLOAD_MEDIA
*/
const UPLOAD_MEDIA = "http://file.api.weixin.qq.com/cgi-bin/media/upload";
/**
* 向微信平台上传图文信息接口地址。
* @var String UPLOAD_NEWS
*/
const UPLOAD_NEWS = "https://api.weixin.qq.com/cgi-bin/media/uploadnews";
/**
* 向公众号用户、用户分组群发图文接口地址。
* @var String MASS_SEND_MESSAGE
*/
const MASS_SEND_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall";
/**
* 从微信平台下载多媒体接口地址。
* @var String DOWNLOAD_MEDIA
*/
const DOWNLOAD_MEDIA = "http://file.api.weixin.qq.com/cgi-bin/media/get";
/**
* 上传永久图文素材。
* @var String ADD_PERMANENT_NEWS
*/
const ADD_PERMANENT_NEWS = "https://api.weixin.qq.com/cgi-bin/material/add_news";
/**
* 上传永久多媒体素材。
* @var String ADD_PERMANENT_MEDIA
*/
const ADD_PERMANENT_MEDIA = "http://api.weixin.qq.com/cgi-bin/material/add_material";
/**
* 获取永久素材。
* @var String GET_PERMANENT_MATERIAL
*/
const GET_PERMANENT_MATERIAL = "https://api.weixin.qq.com/cgi-bin/material/get_material";
/**
* 删除永久图文素材。
* @var String DELETE_PERMANENT_METERIAL
*/
const DELETE_PERMANENT_METERIAL = "https://api.weixin.qq.com/cgi-bin/material/del_material";
/**
* 修改永久图文素材。
* @var String MODIFY_PERMANENT_NEWS
*/
const MODIFY_PERMANENT_NEWS = "https://api.weixin.qq.com/cgi-bin/material/update_news";
/**
* 获取永久图文素材总数量。
* @var String PERMANENT_METERIAL_COUNT
*/
const PERMANENT_METERIAL_COUNT = "https://api.weixin.qq.com/cgi-bin/material/get_materialcount";
/**
* 获取永久图文素材列表。
* @var String PERMANENT_METERIAL_LIST
*/
const PERMANENT_METERIAL_LIST = "https://api.weixin.qq.com/cgi-bin/material/batchget_material";
/**
* ==========微信用户管理:用户分组管理接口地址区域==========
* 本区域接口共6个,分别为:
* 1、创建用户分组;2、查询公众号所有用户分组;3、查询公众号某微信用户所在分组;4、修改公众号用户分组名称;
* 5、移动公众号某用户到某分组;6、批量移动公众号部分用户到某分组;7、删除公众号用户分组。
*/
/**
* 微信平台创建用户分组接口地址。
* @var String CREATE_USER_GROUP
*/
const CREATE_USER_GROUP = "https://api.weixin.qq.com/cgi-bin/groups/create";
/**
* 查询公众号所有用户分组接口地址。
* @var String QUERY_ALL_GROUP
*/
const QUERY_ALL_GROUP = "https://api.weixin.qq.com/cgi-bin/groups/get";
/**
* 查询公众号某微信用户所在分组接口地址。
* @var String QUERY_USER_IN_GROUP
*/
const QUERY_USER_IN_GROUP = "https://api.weixin.qq.com/cgi-bin/groups/getid";
/**
* 修改公众号用户分组名称接口地址。
* @var String ALTER_USER_GROUP_NAME
*/
const ALTER_USER_GROUP_NAME = "https://api.weixin.qq.com/cgi-bin/groups/update";
/**
* 移动公众号某用户到某分组接口地址。
* @var String MOVE_USER_TO_GROUP
*/
const MOVE_USER_TO_GROUP = "https://api.weixin.qq.com/cgi-bin/groups/members/update";
/**
* 批量移动公众号部分用户到某分组接口地址。
* @var String BATCH_MOVE_USER_TO_GROUP
*/
const BATCH_MOVE_USER_TO_GROUP = "https://api.weixin.qq.com/cgi-bin/groups/members/batchupdate";
/**
* 删除公众号用户分组接口地址。
* @var String DELETE_USER_GROUP
*/
const DELETE_USER_GROUP = "https://api.weixin.qq.com/cgi-bin/groups/delete";
/**
* ==========微信用户管理:用户信息及公众号用户列表接口地址区域==========
* 本区域接口共3个,分别为:
* 1、修改公众号用户备注名接口地址;2、获取公众号某关注用户微信基本信息接口地址;3、获取公众号所有关注者用户openid列表。
* 特别注意:引导用户去微信公众平台授权、回跳后得到参数code,继而再拉取用户信息的接口与方法都封装在WeChatAuthorize控制器中,此处不再赘述。
*/
/**
* 修改公众号用户备注名接口地址。
* @var String MODIFY_USER_REMARK_NAME
*/
const MODIFY_USER_REMARK_NAME = "https://api.weixin.qq.com/cgi-bin/user/info/updateremark";
/**
* 获取公众号某关注用户微信基本信息接口地址。
* @var String WECHAT_USER_INFO
*/
const WECHAT_USER_INFO = "https://api.weixin.qq.com/cgi-bin/user/info";
/**
* 获取公众号所有关注者用户openid列表。
* @var String PUBLIC_ALL_SUBSCRIBERS
*/
const PUBLIC_ALL_SUBSCRIBERS = "https://api.weixin.qq.com/cgi-bin/user/get";
/**
* ==========微信自定义菜单功能接口地址区域==========
* 本区域接口共4个,分别为:
* 1、设置公众号菜单;2、查询公众号菜单;3、删除公众号自定义菜单;4、获取公众号自定义菜单配置。
*/
/**
* 设置公众号菜单接口地址。
* @var String SET_PUBLIC_MENU
*/
const SET_PUBLIC_MENU = "https://api.weixin.qq.com/cgi-bin/menu/create";
/**
* 查询公众号菜单接口地址。
* @var String QUERY_PUBLIC_MENU
*/
const QUERY_PUBLIC_MENU = "https://api.weixin.qq.com/cgi-bin/menu/get";
/**
* 删除公众号自定义菜单接口地址。
* @var String DELETE_PUBLIC_MENU
*/
const DELETE_PUBLIC_MENU = "https://api.weixin.qq.com/cgi-bin/menu/delete";
/**
* 获取公众号自定义菜单配置接口地址。
* @var String PUBLIC_MENU_CONFIG
*/
const PUBLIC_MENU_CONFIG = "https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info";
/**
* ==========微信账号管理功能接口地址区域==========
* 本区域接口共3个,分别为:
* 1、创建微信平台公众号二维码;2、下载微信平台公众号二维码;3、微信长链接转短链接接口地址。
*/
/**
* 生成微信平台提供的可关注公众号的二维码地址接口。
* @var String CREATE_QRCODE
*/
const CREATE_QRCODE = "https://api.weixin.qq.com/cgi-bin/qrcode/create";
/**
* 下载微信提供的可关注公众号的二维码地址接口。
* @var String DOWNLOAD_QRCODE
*/
const DOWNLOAD_QRCODE = "https://mp.weixin.qq.com/cgi-bin/showqrcode";
/**
* 微信长链接转短链接接口地址。
* @var String LONG_URL_TO_SHORT
*/
const LONG_URL_TO_SHORT = "https://api.weixin.qq.com/cgi-bin/shorturl";
/**
* ==========微信平台数据统计接口地址区域==========
* 微信数据统计接口需要公众号向微信开放平台授权才能进行。
* 本区域接口共17(2+6+7+2)个,分别为:
* 1、用户分析数据接口(2小类);2、图文分析数据接口(6小类);3、消息分析数据接口(7小类);4、接口分析数据接口(2小类)。
*/
/**
* 获取用户增加数据。
* @var String STATISTIC_GET_USER_SUMMARY
*/
const STATISTIC_GET_USER_SUMMARY = "https://api.weixin.qq.com/datacube/getusersummary";
/**
* 获取累积用户数据。
* @var String STATISTIC_GET_USER_CUMULATE
*/
const STATISTIC_GET_USER_CUMULATE = "https://api.weixin.qq.com/datacube/getusercumulate";
/**
* 获取图文群发每日数据。
* @var String STATISTIC_GET_ARTICLE_SUMMARY
*/
const STATISTIC_GET_ARTICLE_SUMMARY = "https://api.weixin.qq.com/datacube/getarticlesummary";
/**
* 获取图文群发总数据。
* @var String STATISTIC_GET_ARTICLE_TOTAL
*/
const STATISTIC_GET_ARTICLE_TOTAL = "https://api.weixin.qq.com/datacube/getarticletotal";
/**
* 获取图文统计数据。
* @var String STATISTIC_GET_USER_READ
*/
const STATISTIC_GET_USER_READ = "https://api.weixin.qq.com/datacube/getuserread";
/**
* 获取图文统计分时数据。
* @var String STATISTIC_GET_USER_READ_HOUR
*/
const STATISTIC_GET_USER_READ_HOUR = "https://api.weixin.qq.com/datacube/getuserreadhour";
/**
* 获取图文分享转发数据。
* @var String STATISTIC_GET_USER_SHARE
*/
const STATISTIC_GET_USER_SHARE = "https://api.weixin.qq.com/datacube/getusershare";
/**
* 获取图文分享转发分时数据。
* @var String STATISTIC_GET_USER_SHARE_HOUR
*/
const STATISTIC_GET_USER_SHARE_HOUR = "https://api.weixin.qq.com/datacube/getusersharehour";
/**
* 获取消息发送概况数据
* @var String STATISTIC_GET_UPSTREAM_MSG
*/
const STATISTIC_GET_UPSTREAM_MSG = "https://api.weixin.qq.com/datacube/getupstreammsg";
/**
* 获取消息分送分时数据
* @var String STATISTIC_GET_UPSTREAM_MSG_HOUR
*/
const STATISTIC_GET_UPSTREAM_MSG_HOUR = "https://api.weixin.qq.com/datacube/getupstreammsghour";
/**
* 获取消息发送周数据
* @var String STATISTIC_GET_UPSTREAM_MSG_WEEK
*/
const STATISTIC_GET_UPSTREAM_MSG_WEEK = "https://api.weixin.qq.com/datacube/getupstreammsgweek";
/**
* 获取消息发送月数据
* @var String STATISTIC_GET_UPSTREAM_MSG_MONTH
*/
const STATISTIC_GET_UPSTREAM_MSG_MONTH = "https://api.weixin.qq.com/datacube/getupstreammsgmonth";
/**
* 获取消息发送分布数据
* @var String STATISTIC_GET_UPSTREAM_MSG_DIST
*/
const STATISTIC_GET_UPSTREAM_MSG_DIST = "https://api.weixin.qq.com/datacube/getupstreammsgdist";
/**
* 获取消息发送分布周数据
* @var String STATISTIC_GET_UPSTREAM_MSG_DIST_WEEK
*/
const STATISTIC_GET_UPSTREAM_MSG_DIST_WEEK = "https://api.weixin.qq.com/datacube/getupstreammsgdistweek";
/**
* 获取消息发送分布月数据
* @var String STATISTIC_GET_UPSTREAM_MSG_DIST_MONTH
*/
const STATISTIC_GET_UPSTREAM_MSG_DIST_MONTH = "https://api.weixin.qq.com/datacube/getupstreammsgdistmonth";
/**
* 获取接口分析数据
* @var String STATISTIC_GET_INTERFACE_SUMMARY
*/
const STATISTIC_GET_INTERFACE_SUMMARY = "https://api.weixin.qq.com/datacube/getinterfacesummary";
/**
* 获取接口分析分时数据
* @var String STATISTIC_GET_INTERFACE_SUMMARY_HOUR
*/
const STATISTIC_GET_INTERFACE_SUMMARY_HOUR = "https://api.weixin.qq.com/datacube/getinterfacesummaryhour";
/**
* ==========微信小店接口地址区域==========
* 已经使用三方平台商城功能,商家不愿意把商品、存货、销售信息放给微信,该功能暂不开放。
* 1、商品管理接口;2、库存管理接口;3、邮费模板管理接口;4、分组管理接口;5、货架管理接口;6、订单管理接口;7、功能接口。
*/
/**
* ==========微信卡券接口地址区域==========
* 已经使用三方平台优惠券功能,商家不愿意把商品、顾客、优惠券信息放给微信,该功能暂不开放。
* 1、创建卡券接口;2、卡券投放接口;3、卡券核销接口;4、卡券管理接口;5、特殊卡票接口;6、设置测试用户白名单接口。
*/
/**
* ==========微信智能地址区域==========
* 虽然微动已经有了新浪分词接口和智能搜索接口,但是这里还是为了完整,加入微信智能接口部分(语义分析)。
*/
/**
* 微信语义理解代理接口地址。
* @var String WECHAT_SEMANTIC_PROXY
*/
const WECHAT_SEMANTIC_PROXY = "https://api.weixin.qq.com/semantic/semproxy/search";
/**
* ==========微信多客服功能:客服管理接口地址区域==========
* 本区域接口共6个,分别为:
* 1、获取公众号在线客服列表;2、获取公众号在线客服的状态(服务了多少个客户);3、为公众号添加客服账号;
* 4、修改公众号客服信息接口地址;5、上传公众号客服头像接口;6、删除公众号客服账号。
*/
/**
* 获取公众号在线客服列表接口地址。
* @var String CUSTOMER_SERVICE_LIST
*/
const CUSTOMER_SERVICE_LIST = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist";
/**
* 获取公众号在线客服的状态(服务了多少个客户)接口地址。
* @var String CUSTOMER_SERVICE_STATUS
*/
const CUSTOMER_SERVICE_STATUS = "https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist";
/**
* 为公众号添加客服账号接口地址。
* @var String ADD_CUSTOMER_SERVICE
*/
const ADD_CUSTOMER_SERVICE = "https://api.weixin.qq.com/customservice/kfaccount/add";
/**
* 修改公众号客服信息接口地址。
* @var String MODIFY_CUSTOMER_SERVICE_INFO
*/
const MODIFY_CUSTOMER_SERVICE_INFO = "https://api.weixin.qq.com/customservice/kfaccount/update";
/**
* 上传公众号客服头像接口。
* @var String UPLOAD_CUSTOMER_SERVICE_AVATAR
*/
const UPLOAD_CUSTOMER_SERVICE_AVATAR = "http://api.weixin.qq.com/customservice/kfacount/uploadheadimg";
/**
* 删除公众号客服账号。
* @var String UPLOAD_CUSTOMER_SERVICE_AVATAR
*/
const DELETE_CUSTOMER_SERVICE = "https://api.weixin.qq.com/customservice/kfaccount/del";
/**
* ==========本类私有变量区域==========
*/
/**
* 当前企业的e_id。
*
* @var String $e_id
*/
private $e_id = '';
/**
* 开启开发者模式时填写的token。
*
* @var String $developertoken
*/
private $developertoken = '';
/**
* 企业开发者模式的APPID。
*
* @var String $appid
*/
private $appid = '';
/**
* 企业开发者模式的APPSECRET.
*
* @var String $appsecret
*/
private $appsecret = '';
/**
* 是否开启本类调试模式,若开启则忽略验证签名。
*
* @var boolean $debug
*/
private $debug = false;
/**
* 微信推送过来的数据或响应数据(XML被解析成二维数组形式)
*
* @var array $data
*/
private $data = array ();
/**
* 微动服务器主动发送给微信服务器的数据。
* @var array $send
*/
private $send = array ();
/**
* 接口调用时产生的错误信息,默认OK
* @var String $error
*/
private $error = "ok";
/**
* 调用操作修改类微信接口(非返回信息类)产生的结果数组(errcode,errmsg)。
* @var array $result
*/
private $result;
/**
* 是否开启aes密文加密传输。
* @var boolean $encode
*/
private $encode = FALSE;
/**
* 开启aes密文传输的加密密钥
* @var string $AESKey
*/
private $AESKey = '';
/**
* 定义http请求头格式。
* @var array $header
*/
private $header = array ( 'Content-type' => 'text/html', 'charset' => 'utf-8' );
/**
* 是否授权
* @var unknown
*/
private $is_auth = 0;
/**
* 本类WeactWechat的构造函数。
* @param array $options 创建微动微信类的信息数组,包含如下字段信息:
* @property string e_id 企业编号
* @property string appid 企业开发者APPID
* @property string appsecret 企业开发者APPSECRET
* @property string developertoken 企业在微动平台接入开发者模式的token,可以自行修改,默认123456
* @property boolean encode 是否需要开启密文传输
* @property string aeskey 如果开启密文传输,aes的加密key
* @property boolean debug 是否开启调试模式
*/
public function __construct($options = array ()) {
$this->e_id = isset ( $options ['e_id'] ) ? $options ['e_id'] : ''; // 本类要操作的企业编号(微动平台下的)
$this->appid = isset ( $options ['appid'] ) ? $options ['appid'] : ''; // 本类要操作的APPID
$this->appsecret = isset ( $options ['appsecret'] ) ? $options ['appsecret'] : ''; // 本类要操作的APPSecret
$this->developertoken = isset ( $options ['developer_token'] ) ? $options ['developer_token'] : '123456'; // 本类要操作的开发者模式token
$this->encode = ! empty ( $options ['msg_encode'] ) ? true : false; // 是否需要对微信消息进行加密
$this->AESKey = isset ( $options ['aeskey'] ) ? $options ['aeskey'] : ''; // AES加密的Key
$this->is_auth = isset ( $options ['is_auth'] ) ? $options ['is_auth'] : 0; // 是否微信open平台的授权调用
$this->debug = isset ( $options ['debug'] ) ? $options ['debug'] : false; // 是否开启调试模式
// 判断是否传入了企业信息、appid和appsecret,三者都不为空才创建对象
if (empty ( $this->e_id ) || empty ( $this->appid ) || empty ( $this->appsecret )) {
$this->error = "创建微信接口层失败,企业编号、企业开发者appid和appsecret都不能为空!";
return false;
}
// 如果开启了加密传输消息,则判断加密AESKey是否长度正确
if ($this->encode && strlen ( $this->AESKey ) != 43) {
$this->error = 'AESKey Lenght Error.'; // AESKey加密密钥长度错误
return false;
}
}
/**
* ==========基本类变量读写函数区域==========
*/
/**
* 返回当前类的商家编号。
* @return string $e_id 微动企业编号
*/
public function gete_id(){
return $this->e_id;
}
/**
* 返回当前类的商家APPID。
* @return string $appid 企业开发者模式appid
*/
public function getAPPID(){
return $this->appid;
}
/**
* 返回当前类的商家APPSecret。
* @return string $appsecret 企业开发者模式appsecret
*/
public function getAPPSecret(){
return $this->APPSecret;
}
/**
* 方便开发者调试维护的函数,查看该微信类的商家配置(微动平台)。
*/
public function getConfig() {
$configinfo = array (
'e_id' => $this->e_id, // 微动平台商家编号
'developertoken' => $this->developertoken, // 开发者模式填写的token
'appid' => $this->appid, // 开发者模式appid
'appsecret' => $this->appsecret, // 开发者模式appsecret
'debug' => $this->debug, // 是否开启接口调试模式
'data' => $this->data, // 微信发来的POST消息数据(二维数组)
'send' => $this->send, // 准备要发送给微信用户的数据(二维数组)
'error' => $this->error, // 微信接口调用失败解析的错误信息
'result' => $this->result, // 微信操作类接口调用后产生的结果信息
'encode' => $this->encode, // 微信POST来的消息数据是否开启AES加解密
'AESKey' => $this->AESKey // 该商家的aes加密密钥
);
return $configinfo;
}
/**
* ==========本类私有函数区域==========
*/
/**
* 私有敏感函数:向微动中控系统请求access_token函数。
* 该接口类型为GET。
* @return string $access_token 企业的token信息
*/
private function getToken($appid = '', $query_auth_code = '') {
$url = ""; // 全局请求url
if (empty ( $appid )) {
// 正常情况下请求中控系统
$url = self::WECHAT_TOKEN_CENTRAL_SYSTEM; //请求获取accesstoken的url
$params ['e_id'] = $this->e_id; //商家编号
$params ['is_auth'] = $this->is_auth; //商家是否授权开关
} else {
// 全网发布测试
$url = self::OPEN_TOKEN_CENTRAL_SYSTEM; //请求获取accesstoken的url
$params ['appid'] = $appid; // 微信全网发布测试用appid
$params ['query_auth_code'] = $query_auth_code; // 授权auth_code
}
$httpstr = http ( $url, $params ); //使用http方法获取服务器返回数据$httpstr
$jsonresult = json_decode ( $httpstr, true ); //使用json格式对数据解码,第二个参数为true时,将返回数组而非对象object
return $jsonresult ['access_token'];
}
/**
* ==========微信接口验证准备工作==========
*/
/**
* 验证URL有效性,在request解析数据前调用。
*/
public function valid() {
$echoStr = $_GET ["echostr"]; // 尝试获取GET字段
if (isset ( $echoStr )) {
// 如果验证URL
if ($this->checkSignature ()) {
//echo $echoStr; // 验证成功则输出到页面上
exit ( $echoStr ); // 验证成功则输出到页面上
} else {
exit ( "Access Denied! 身份验证失败,拒绝响应非微信发来的数据,谢谢合作!" );
}
}
return true;
}
/**
* 对数据进行签名认证,确保是微信发送的数据,原auth函数。
* @return boolean true-签名正确,false-签名错误
*/
public function checkSignature() {
if ($this->debug) return true; // 如果本类处于调试状态,直接返回真
$signature = $_GET ['signature']; // 获取消息签名
$timestamp = $_GET ['timestamp']; // 获取消息时间戳
$nonce = $_GET ['nonce']; // 获取消息随机数
if (empty ( $signature ) || empty ( $timestamp ) || empty ( $nonce )) {
return false; // 如果消息的前民个、时间戳或随机数是空的,则返回false
}
$token = $this->developertoken; // 取当前的开发者模式token
if (! $token) return false; // 如果实例化类的时候不传入token,直接返回false
$tmpArr = array ( $token, $timestamp, $nonce ); // Step1:把开发者模式token,时间戳和随机数放入数组中
sort ( $tmpArr, SORT_STRING ); // Step2:对数组数据进行字典排序
$tmpStr = implode ( $tmpArr ); // Step3:切分数组
return sha1 ( $tmpStr ) == $signature; // Step4:比对签名是否正确
}
/**
* 获取微信推送的数据,包含两个:1、验证真实性;2、接收一般消息。
* @return array 转换为数组后的数据
*
* 在这里声明下微信的数据格式:
* <xml>
* <ToUserName><![CDATA[toUser]]></ToUserName> 开发者微信号
* <FromUserName><![CDATA[fromUser]]></FromUserName> 发送方帐号(一个OpenID)
* <CreateTime>1348831860</CreateTime> 消息创建时间 (整型)
* <MsgType><![CDATA[text]]></MsgType> 消息类型
* <Content><![CDATA[this is a test]]></Content> 消息内容
* <MsgId>1234567890123456</MsgId> 消息id,64位整型,消息的主键,可以用来查重
* </xml>
*
* 2014/06/22 03:24:25 写入。
*
*/
public function request() {
$postStr = $GLOBALS ["HTTP_RAW_POST_DATA"]; // 获取微信POST推送过来的数据
if (! empty ( $postStr )) {
// 如果消息不空
$this->data = self::extractXml ( $postStr ); // 抽取微信推送的消息,解码成data(我已经修改成不转为小写字母,尊重微信原来的字段名称,注意!)
if ($this->encode && ! empty ( $this->AESKey )) {
// 如果该企业开启密文,且数据库已配置
$datadecode = $this->AESdecode ( $this->data ['Encrypt'] ); // 直接对其进行解密
if (! empty ( $datadecode )) {
$this->data = $datadecode; // 返回aes解码后的结果
}
}
return $this->data; // 返回解析后的数据
} else {
// 空消息不予理会
exit ( "" ); // 直接将空消息输出
return false;
}
// 原来的解析
/* $xml = file_get_contents ( "php://input" ); // php读取文件函数file_get_contents(),读入xml文件,file_get_contents("php://input")代表php文件输入流
$xml = new SimpleXMLElement ( $xml ); // 使用php的SimpleXMLElement()函数来解析xml
$xml || exit ( '' ); // 如果解析的xml是空文档则退出
p($xml);die;
foreach ( $xml as $key => $value ) { // 使用php的foreach循环,将解码后的xml的键和值对应转成数组
$this->data [$key] = strval ( $value ); // 本类中定义了$data数组,将解码后的xml转成格式data['键值']=字符串值,strval()函数是php转字符串
}
if ($this->encode) {
// 如果该企业开启密文
$datadecode = $this->AESdecode ( $this->data ['encrypt'] ); // 直接对其进行解密
$this->data = $datadecode; // 返回aes解码后的结果
}
return $this->data; // 返回将xml转成的数组 */
}
/**
* 获取微信的数据。
*/
public function requestOpen($openmsgdata = NULL) {
$this->data = $openmsgdata;
}
/**
* ==========微信接口部分函数==========
* 以下部分封装各种各样的微信接口函数。
*/
/**
* 基础支持:获取微信服务器IP地址,已调通。
* @return array $wechatiplist 微信地址列表
*/
public function wechatServerIP() {
$params ['access_token'] = $this->getToken ();
$serverIPJson = http ( self::WECHAT_SERVER_IP, $params );
$jsonArr = $this->parseJson ( $serverIPJson );
return $jsonArr;
}
/**
* ==========被动回复用户消息接口部分==========
*/
/**
* 被动响应微信发送的信息(被动回复),密文模式已调通。
* @param string $to 接收用户名
* @param string $from 发送者用户名
* @param array $content 回复信息,文本信息为string类型
* @param string $type 消息类型
* @param string $flag 是否新标刚接受到的信息
* @return string XML字符串
*/
public function response($content, $type = 'text', $flag = 0) {
/* 原来SDK的代码:定义本类的基础数据$data */
$timenow = NOW_TIME;
$this->data = array(
'ToUserName' => $this->data ['FromUserName'], //$weixin中有request的$data数据,取出FromUserName作为被回复者(用户)
'FromUserName' => $this->data ['ToUserName'], //$weixin中有request的$data数据,取出ToUserName作为回复者(公众号)
'CreateTime' => $timenow, //当前时间
'MsgType' => $type, //取消息类型
);
/* 添加类型数据 */
$this->$type ( $content );
/* 添加状态 */
$this->data ['FuncFlag'] = $flag; // (这里我先省去了,形参中原来有个$flag = 0标识自己服务器的新旧消息)
/* 转换数据为XML */
$response = self::array2Xml ( $this->data );
if ($this->is_auth == 0) {
// 普通接入回复模式
if ($this->encode) {
// 如果采用密文模式,则加密后再发送
$nonce = $_GET ['nonce']; // $nonce用$_GET ['nonce']获取!2015/04/24,不可以自己生成一个,否则签名比对不上
//$nonce = md5 ( $timenow . randCode ( 4, 1 ) );
$xmlStr ['Encrypt'] = $this->AESencode ( $response ); // 采用密文模式加密
$xmlStr ['MsgSignature'] = self::getSHA1 ( $xmlStr ['Encrypt'], $nonce );
$xmlStr ['TimeStamp'] = $timenow;
$xmlStr ['Nonce'] = $nonce;
$response = '';
$response = self::array2Xml ( $xmlStr ); // 将本类数组$data转换数据为XML
}
} else if ($this->is_auth == 1) {
// 开放平台回复模式
$appId = C ( 'COMPONENT_APPID' );
$token = C ( 'COMPONENT_TOKEN' );
$encodingAesKey = C ( 'COMPONENT_ASEKEY' );
$timestamp = $_GET ['timestamp'];
$nonce = $_GET ['nonce'];
$openresponse = "";
$msgcrypt = new WXBizMsgCrypt ( $token, $encodingAesKey, $appId );
$errCode = $msgcrypt->encryptMsg ( $response, $timeStamp, $nonce, $openresponse );
if ($errCode == 0) {
$response = $openresponse; // 开放平台回包加密成功
} else {
$response = ""; // 开放平台回包加密出错
}
}
exit ( $response ); // 输出结果回应微信
}
/**
* 回复文本信息(被动回复)。
* @param string $content 要回复的信息
*/
private function text($content){
$this->data['Content'] = $content;
}
/**
* 回复音乐信息(被动回复)。
* @param string $content 要回复的音乐
*/
private function music($music){
$this->data['Music'] = $music;
}
/**
* 回复图文信息(被动回复)。
* @param string $news 要回复的图文内容
*/
private function news($news){
$articles = array();
foreach ($news as $key => $value) {
$articles[$key]['Title'] = $value['Title'];
$articles[$key]['Description'] = $value['Description'];
$articles[$key]['PicUrl'] = $value['PicUrl'];
$articles[$key]['Url'] = $value['Url'];
if ($key >= 9) { break; } //最多只允许10条新闻
}
$this->data['ArticleCount'] = count($articles);
$this->data['Articles'] = $articles;
}
/**
* ==========主动发送客服消息接口部分==========
*/
/**
* 主动发送消息(客服接口),此函数为类外可以调用的客服消息发送函数,已调通。
* 该函数执行消息的打包,最终发送还需要调用本类内部的私有函数send。
* @param string $content 要发送的消息内容
* @param string $openid 要发送给的微信用户openid
* @param string $msgtype 要发送消息的类型
* @param string $kf_account 可选字段:(微信6.0.2版本以上可用)客服账号昵称及自定义头像
* @return array 微信服务器返回的发送结果信息(json_decode后的数组格式)
*/
public function sendMsg($content, $openid = '', $msgtype = 'text', $kf_account = '') {
/* 基础数据 $send = array();已经简写 */
$this->send ['touser'] = $openid; //设置数组$send(当前函数中的变量$this->)的touser(发送给谁)
$this->send ['msgtype'] = $msgtype; //设置数组$send的发送类型:文本信息类型
/* 添加类型数据 */
$sendtype = 'send' . $msgtype; // 拼接不同的函数名称
$this->$sendtype ( $content ); // 多态调用不同函数名
/* 处理新添加的客服信息 */
if (! empty ( $kf_account )) {
$this->send ['customservice'] ['kf_account'] = $kf_account; // 如果客服账号不空,则添加客服账号
}
/* 发送 */
$sendjson = jsencode ( $this->send ); // 压缩要发送的数据包,采用无转义字符方式压缩
$url = self::SEND_CUSTOMER_SERVICE_MESSAGE . "?access_token=" . $this->getToken (); // 拼接发送信息API的URL请求地址
$httpresult = http ( $url, $sendjson, 'POST', $this->header, true ); // 调用Common公有的http()函数发送给微信服务器
$sendresult = $this->parseJson ( $httpresult ); // 解析发送客服消息结果
return $sendresult;
}
/**
* 全网发布主动发送消息(客服接口),此函数为类外可以调用的客服消息发送函数,已调通。
* 该函数执行消息的打包,最终发送还需要调用本类内部的私有函数send。
* @param string $content 要发送的消息内容
* @param string $openid 要发送给的微信用户openid
* @param string $appid
* @param string $query_auth_code 全网发布测试公众号查询授权码
* @param string $msgtype 要发送消息的类型
* @return array 微信服务器返回的发送结果信息(json_decode后的数组格式)
*/
public function sendOpenMsg($content, $openid = '', $appid = '', $query_auth_code = '', $msgtype = 'text') {
/* 基础数据 $send = array();已经简写 */
$this->send ['touser'] = $openid; //设置数组$send(当前函数中的变量$this->)的touser(发送给谁)
$this->send ['msgtype'] = $msgtype; //设置数组$send的发送类型:文本信息类型
/* 添加类型数据 */
$sendtype = 'send' . $msgtype; // 拼接不同的函数名称
$this->$sendtype ( $content ); // 多态调用不同函数名
/* 发送 */
$sendjson = jsencode ( $this->send ); // 压缩要发送的数据包,采用无转义字符方式压缩
$opentoken = $this->getToken ( $appid, $query_auth_code );
$url = self::SEND_CUSTOMER_SERVICE_MESSAGE . "?access_token=" . $opentoken; // 拼接发送信息API的URL请求地址
$httpresult = http ( $url, $sendjson, 'POST', $this->header, true ); // 调用Common公有的http()函数发送给微信服务器
$sendresult = $this->parseJson ( $httpresult ); // 解析发送客服消息结果
debugLog ( $appid . "\n" . $query_auth_code . "\n" . $opentoken . "\n" . $httpresult . "\n\n" ); // 记录日志
return $sendresult;
}
/**
* 主动发送(客服接口)文本消息,已调通。
* @param string $content 要发送的信息
*/
private function sendtext($content) {
$this->send ['text'] = array (
'content' => $content
);
}
/**
* 主动发送(客服接口)图片消息,已调通。
* @param string $content 要发送的信息
*/
private function sendimage($content) {
$this->send ['image'] = array (
'media_id' => $content
);
}
/**
* 主动发送(客服接口)视频消息。
* @param string $content 要发送的信息
*/
private function sendvideo($video){
list (
$video ['media_id'],
$video ['title'],
$video ['description']
) = $video;
$this->send ['video'] = $video;
}
/**
* 主动发送(客服接口)语音消息,已调通。
* @param string $content 要发送的信息
*/
private function sendvoice($content) {
$this->send ['voice'] = array (
'media_id' => $content
);
}
/**
* 主动发送(客服接口)音乐消息。
* @param string $content 要发送的信息
*/
private function sendmusic($music) {
$this->send ['music'] = $music;
}
/**
* 主动发送(客服接口)图文消息,已调通。
* 已经修复原来SDK的错误。
* 修复时间:2014/07/05 02:23:25.
* Author:赵臣升。
* @param string $news 要回复的图文内容
*
* $news消息格式:(注意都是小写).
* $content[$i]['title'] = '标题';
* $content[$i]['description'] = '描述';
* $content[$i]['picurl'] = '封面地址';
* $content[$i]['url'] = '具体地址';
*/
private function sendnews($news) {
$articles = array ();
$k = 0; // 图文条数
foreach ($news as $key => $value) {
if ($k > 9) { break; } // 最多只允许10条图文(也最多只装入10条图文)
$articles [$k] ['title'] = $value ['title'];
$articles [$k] ['description'] = $value ['description'];
$articles [$k] ['url'] = $value ['url'];
$articles [$k] ['picurl'] = $value ['picurl'];
$k ++; // 赋值一条图文后,k值+1
}
$finalnews ['articles'] = $articles; // 图文放入articles索引中
$this->send ['news'] = $finalnews; // 整个articles放入news索引中