【EasyWeChat】http与console的缓存不通用导致报错Credential "component_verify_ticket" does not exist in cache的解决方法
EasyWeChat是什么,在这里就不多说了。
【测试环境】
Windows10
php7.2.10
Apache2.4
Laravel5.4
做微信开发有一段时间了,一开始使用微信官方接口进行开发。后来改用EasyWeChat微信开发SDK,使用EasyWeChat后确实方便很多。但遇到一个问题,这个问题就是:在开发微信开放平台的时候,通过http路由访问时,所有功能都是没问题的,但是通过命令行console去实现消息发送的时候就会报错【Credential "component_verify_ticket" does not exist in cache】,当时由于时间紧迫,没怎么去考虑问题的原因,临时采用了比较掉牙的方法勉强实现了功能,就是通过新建一个路由,然后把原来命令需要执行的过程变为路由控制器执行的过程,最后通过原命令请求这个新建的路由。此方法留下了很多隐患,比如:如果路由外泄,谁都能去操作控制器的执行过程,这不是我们想看到的,当然你也可以加一些其他的辅助代码去规避一些可预见的不利操作(这样的话就有违Laravel框架的优雅)。
现在我们来分析原因:通过http访问没问题,说明component_verify_ticket是缓存成功的;通过console执行却说component_verify_ticket不在缓存内,初步判断应该是缓存驱动的问题。曾一度以为EasyWeChat的缓存配置与Laravel框架的缓存配置默认项是一致的,因为EasyWeChat的配置文件中有个use_laravel_cache配置项(其实这个配置项在目前来看没什么卵用)。
Laravel配置的是Redis缓存,通过查看EasyWeChat源码,找到component_verify_ticket缓存对应的键为
easywechat.kernel.access_token.【APPID】
然后在Redis中模糊查找 keys access_token ,发现没有匹配到结果,说明EasyWeChat的缓存驱动和Laravel框架配置的默认缓存驱动是不一样的。
❓EasyWeChat缓存不存在Redis中,那到底存在哪里了呢?飞外太空了?
查看了EasyWeChat官方文档后,文档是这么说的【EasyWeChat项目使用 symfony/cache 来完成缓存工作,SDK 中的所有缓存默认使用文件缓存,缓存路径取决于 PHP 的临时目录】
默认使用文件缓存,那就在Laravel下找文件缓存的位置\storage\framework\cache\data呗,然而目录下也没发现有任何文件,说明EasyWeChat的文件缓存路径与Laravel框架的文件缓存路径也是不一样的,即使你配置了use_laravel_cache(那个没什么卵用的配置项)为true。
再往后看,缓存路径取决于 PHP 的临时目录,那就是PHP的配置问题的。通过http访问与通过console执行,PHP的临时目录不一致。
进行了测试:分别进行http访问输出sys_get_temp_dir()和console执行命令记录sys_get_temp_dir(),结果也在预料之内,不一样的结果:前者C:/Windows/Temp,后者C:\Users\z\AppData\Local\Temp。
最初的问题已转变为:如何使http过程中的PHP临时目录与console过程中的PHP临时目录保持一致?
一般情况下安装PHP时,很多人不会去配置php.ini文件的 sys_temp_dir 选项。这个选项主要就是配置PHP 的临时目录。sys_temp_dir 选项默认是关闭的,在windows系统下默认配置的PHP的临时目录为C:/Windows/Temp。
配置sys_temp_dir 选项:sys_temp_dir = "C:/Windows/Temp"
再进行测试:进行http访问输出sys_get_temp_dir()和console执行命令记录sys_get_temp_dir(),结果:两者都是C:/Windows/Temp
回到项目再进行测试,发现问题不存在了。