简介: 本篇博文是针对本人上传的企业微信PHP-SDK进行讲解的,因为当时开发企业微信时,一直没有找到相关的参考资料,官方提供的PHP-SDK也是存在各种问题,所以在这里介绍一下自己开发过程中遇到的问题和解决方法,如果问题或异议,欢迎讨论
1) PHP-SDK采用的是DI(依赖注入)容器设计模式构建的,DI可以使得代码降低代码的耦合度,但是要求开发者对各个功能类都要有一定的了解,因为DI容器需要开放者指定对象注入到工具类中,才能调用相应的功能方法来实现对应的功能,这样说比较抽象,来个实例说明一下(以ThinkPHP5框架为例):
// 用户类
class User extends \think\Model // \think\Model是数据库基类,Tp5的框架源码类
{
public $name = null;
public $sex = null;
public $email = null;
//构造方法
public function __construct($name = null, $sex = null, $email = null) {
$this->name = $name;
$this->sex = $sex;
$this->email = $email;
}
// 新增用户数据
public function addUser() {
$data = [
'username' => $this->name,
'sex' => $this->sex,
'email' => $this->email
];
return $this->insert($data); //add()方法将数据插入数据库
// $this->insert($data); // 演示示例 2
}
}
//工具类
class Tool
{
public $obj = null;
public function __construct($object) {
$this->obj = $object;
}
//新增数据库记录
public function add() {
return $this->obj->addUser(); //添加数据
// $this->obj->addUser(); // 演示示例 2
}
}
$userObj = new User();
$userObj->name = '王二麻子';
$userObj->sex = '保密';
$userObj->email = '[email protected]';
$toolObj = new Tool($user);
$toolObj->add();
解释: 将User类实例化为对象$userObj,并为对象$userObj属性赋值,再将对象$userObj注入到Tool类中; 此处的Tool类,类似一个中转站,只负责传递对象,具体的功能仍由对象中的功能方法实现;以上就是一个最简单的依赖注入模型;
2) 此SDK中, DI(依赖注入)容器 虽然可以降低代码耦合度,但是因为每个人使用的习惯问题, 有些人可能会将值通过进行传递,而不会在方法中直接return 执行结果,如 演示示例2 所示, 这样的不足在于,当代码因发生中断时,属性值会丢失,所以可以将一些必要的值进行缓存,比如 接口的token值, 就可以缓存在redis/memcached, 而不是存放在类的属性中;
1)
├─weworkapi
│ ├─api 功能接口目录
│ │ ├─datastructure 功能类目录
│ │ │ ├─approvaldata OA数据接口
│ │ │ ├─batch 批量数据处理目录
│ │ │ ├─checkdata 打卡数据目录1(OA数据子集)
│ │ │ ├─checkoption 打卡数据目录2(OA数据子集)
│ │ │ ├─external 外部联系人目录
│ │ │ ├─invoice 电子发票目录
│ │ │ ├─menu 自建应用主页菜单目录
│ │ │ ├─message 自建应用消息目录
│ │ │ ├─oauth oAuth权限认证目录
│ │ │ ├─pay 企业微信支付目录
│ │ │ ├─servicecrop 第三方服务商功能类
│ │ │ ├─servicecrop 第三方服务商功能类
│ │ │ ├─tag 标签目录
│ │ │ ├─user 企业成员目录
│ │ │ ├─Agent.php 自建应用类
│ │ │ └─Department.php 企业部门类
│ │ ├─examples 测试例子目录(仅供参考,修改后可能无效)
│ │ ├─ src 工具类目录(类似第一点中结束的Tool类作用)
│ │ │ ├─API.php 工具基类
│ │ │ ├─CorpAPI.php 企业工具类
│ │ │ ├─ServiceCorpAPI.php 为服务商开放的接口,使用应用授权的token
│ │ │ └─ServiceProviderAPI.php 为服务商开放的接口,使用应用授权的token
│ │
│ ├─callback 回调操作(第三方或服务商回调的操作)
│ │
│ ├─utils 异常类目录
│ │ ├─Utils.php 公共功能类
│ │ ├─HttpUtils.php 的curl请求http参数处理类
│ │ └─... 其他的都是异常处理类
│ │
│ ├─config.php 调试配置文件
│ ├─README.md
1) 修改后的PHP-SDK中 部分文件中有
use \think\Cache;
use \think\Config;
use \think\Request;
这些类均为ThinkPHP5.*中的源码基类, 只要使用的是ThinkPHP5.*的框架都不会出错,但是这些文件中的配置需要自行添加,
A) 如本人使用的cache是redis 需要在 /application/config.php 的 cache配置中添加redis的配置信息;
B) SDK 中有很多处加载过Config::get('wework') , 或Config::get('wework.CORP_ID');
是在config.php中添加了企业微信配置信息(二维数组)
'wework' => [
'CORP_ID' => '你的企业ID',
'CORP_SECRET' => '你的企业微信SECRET', // 有读写权限的secret
'CORP_EXTERNAL_SECRET' => '只读权限的SECRET', //外部联系人接口使用的是只读权限的secret
];
1) 部分代码出错
A) 问题: 修改前的PHP-SDK中的Untils中有些判断 $val == null , 导致 to_invite = false 时失效(to_invite是否邀请外部成员加入企业微信)
B) 解决方案: 使用 $valu === null 判断, 目前已修正
2) 接口调用过程不清晰问题
A) 问题: 无法监控企业微信接口调用的情况
B)解决方法: 在企业微信接口调用时,将调用记录写入日志表,目前记录调用日志的代码已植入/weworkapi/api/src/API.php中_addApiLogs 方法, 只需根据_addApiLogs方法的键名作为字段,在数据建立一个日志表即可
3) token和调用频次的处理
A) 因为token都有时效性,一般token有效期为7200秒,且系统会限制token的调用频次(限制阈值,如: 获取token接口调用次数不得超过 20次/天)
B) 这个问题是出于个人建议,因为时间关系,目前还没有在SDK实践,就是将SDK中的access_token,provider_token,等存入缓存中,(目前SDK是将这些token的值都存放在属性中),这时token值存入缓存明显更稳定了
C) 不仅是token, 包括SDK中还涉及到获取JS-SDK的ticket和 jsApiTicket 等值,ticket值和jsApiTicket都和token类似,因此可以考虑使用缓存记录ticket值和jsApiTicket,并设定缓存有效期; 其实涉及到调用频次限制的问题,都可以考虑缓存进行解决
4) 另外还需注意一个重要问题,企业微信的接口调用次数,数据处理量也有严格的限制,具体请参照企业微信官方文档,
1) SDK修改前后对比:
A) 修改前: 原SDK是以面向过程的思维处理的,可直接通过include 文件进行调用,无法再框架中直接使用
B) 修改后: 依据PSR规范对部分代码进行修改, SDK的结构遵循Tp5的目录格式(即PSR规范)
2) 调试工具
1) 这一点官方文档也有,但是光从文字上很难理解,工具文件名为 devtools_resources.pak
2) 安装方法: 将devtools_resources.pak 文件下载到本地,并将此文件放入企业微信安装包路径的根目录下,也就是对应的版本目录下,并重启企业微信客户端生效
3) 使用方法:
4) 注意:
A) 问题: 文件按 2) 中步骤操作完后,有时按照 3) 步骤 打开调试工具,会发现调试工具页面一片空白,
B) 原因: 这说明devtools_resources.pak 文件丢失了, 常发生在企业微信客户端版本升级,因为升级时,旧版本号对应目录会被清空,同时devtools_resources.pak文件也被删除了
C) 本地自行备份,企业微信客户端升级后,只需将devtools_resources.pak文件重新放入最新的版本号目录根目录下(建议下载完devtools_resources.pak文件后,自行备份devtools_resources.pak文件)
5) 下载地址: 可以到本人的上载资源中下载(老弟学习也需要下载一些积分的资源,多包涵)
3) 最后,因为目前开发暂未涉及到SDK所有内容,可能有些地方的bug还没发现, 目前本人亲试过的几块内容有: 外部联系人模块 /weworkapi/api/datastructure/external, 应用消息发送模块 /weworkapi/api/datastructure/message (目前实现了图文类型,文本类型亲测有用), 应用菜单模块 /weworkapi/api/datastructure/menu 等