Total Complexity | 79 |
Total Lines | 778 |
Duplicated Lines | 0 % |
Changes | 22 | ||
Bugs | 0 | Features | 0 |
Complex classes like WebAppService often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use WebAppService, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
33 | class WebAppService extends Service |
||
34 | { |
||
35 | /** |
||
36 | * 公众号的唯一标识 |
||
37 | * @var |
||
38 | */ |
||
39 | private $app_id; |
||
40 | |||
41 | /** |
||
42 | * 公众号的appsecret |
||
43 | * @var |
||
44 | */ |
||
45 | private $app_secret; |
||
46 | |||
47 | /** |
||
48 | * 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理 |
||
49 | * @var |
||
50 | */ |
||
51 | private $redirect_uri; |
||
52 | |||
53 | /** |
||
54 | * 返回类型,请填写code |
||
55 | * @var string |
||
56 | */ |
||
57 | private $response_type = 'code'; |
||
58 | |||
59 | /** |
||
60 | * @var string |
||
61 | */ |
||
62 | private $scope = "snsapi_base"; |
||
63 | |||
64 | /** |
||
65 | * @var string |
||
66 | */ |
||
67 | private $state = ""; |
||
68 | |||
69 | /** |
||
70 | * @var string |
||
71 | */ |
||
72 | private $grant_type = "authorization_code"; |
||
73 | |||
74 | /** |
||
75 | * 驱动方式 |
||
76 | * @var string |
||
77 | */ |
||
78 | private $cache = "file"; |
||
79 | |||
80 | /** |
||
81 | * 商户平台设置的密钥key |
||
82 | * @var |
||
83 | */ |
||
84 | private $mch_key; |
||
85 | |||
86 | /** |
||
87 | * @param string $mchKey |
||
88 | * @return $this |
||
89 | */ |
||
90 | public function mchKey(string $mchKey) |
||
91 | { |
||
92 | $this->mch_key = $mchKey; |
||
93 | return $this; |
||
94 | } |
||
95 | |||
96 | /** |
||
97 | * 商户号 |
||
98 | * @var |
||
99 | */ |
||
100 | private $mch_id; |
||
101 | |||
102 | /** |
||
103 | * 商户号 |
||
104 | * @param string $mchId |
||
105 | * @return $this |
||
106 | */ |
||
107 | public function mchId(string $mchId) |
||
108 | { |
||
109 | $this->mch_id = $mchId; |
||
110 | return $this; |
||
111 | } |
||
112 | |||
113 | /** |
||
114 | * 公众号的唯一标识 |
||
115 | * @param string $appId |
||
116 | * @return $this |
||
117 | */ |
||
118 | public function appId(string $appId): self |
||
119 | { |
||
120 | $this->app_id = $appId; |
||
121 | return $this; |
||
122 | } |
||
123 | |||
124 | /** |
||
125 | * 公众号的appsecret |
||
126 | * @param string $appSecret |
||
127 | * @return $this |
||
128 | */ |
||
129 | public function appSecret(string $appSecret): self |
||
130 | { |
||
131 | $this->app_secret = $appSecret; |
||
132 | return $this; |
||
133 | } |
||
134 | |||
135 | /** |
||
136 | * 获取配置信息 |
||
137 | * @return $this |
||
138 | */ |
||
139 | private function getConfig(): self |
||
140 | { |
||
141 | $this->cache = config('dtapp.wechat.webapp.cache'); |
||
|
|||
142 | $this->app_id = config('dtapp.wechat.webapp.app_id'); |
||
143 | $this->app_secret = config('dtapp.wechat.webapp.app_secret'); |
||
144 | return $this; |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理 |
||
149 | * @param string $redirectUri |
||
150 | * @return $this |
||
151 | * @throws DtaException |
||
152 | */ |
||
153 | public function redirectUri(string $redirectUri) |
||
154 | { |
||
155 | if (empty(Pregs::isLink($redirectUri))) { |
||
156 | throw new DtaException("请检查redirectUri,是否正确"); |
||
157 | } |
||
158 | $this->redirect_uri = Urls::lenCode($redirectUri); |
||
159 | return $this; |
||
160 | } |
||
161 | |||
162 | /** |
||
163 | * 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 ) |
||
164 | * @param string $scope |
||
165 | * @return $this |
||
166 | * @throws DtaException |
||
167 | */ |
||
168 | public function scope(string $scope): self |
||
169 | { |
||
170 | if ($scope === "snsapi_base") { |
||
171 | $this->scope = $scope; |
||
172 | } elseif ($scope === "snsapi_userinfo") { |
||
173 | $this->scope = $scope; |
||
174 | } else { |
||
175 | throw new DtaException("请检查scope参数"); |
||
176 | } |
||
177 | return $this; |
||
178 | } |
||
179 | |||
180 | /** |
||
181 | * 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 |
||
182 | * @param string $state |
||
183 | * @return $this |
||
184 | */ |
||
185 | public function state(string $state): self |
||
186 | { |
||
187 | $this->state = $state; |
||
188 | return $this; |
||
189 | } |
||
190 | |||
191 | /** |
||
192 | * 驱动方式 |
||
193 | * @param string $cache |
||
194 | * @return $this |
||
195 | */ |
||
196 | public function cache(string $cache): self |
||
197 | { |
||
198 | $this->cache = $cache; |
||
199 | return $this; |
||
200 | } |
||
201 | |||
202 | /** |
||
203 | * 网页授权 |
||
204 | * https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0 |
||
205 | * @return void |
||
206 | * @throws DtaException |
||
207 | */ |
||
208 | public function oauth2() |
||
209 | { |
||
210 | if (empty($this->app_id)) { |
||
211 | $this->getConfig(); |
||
212 | } |
||
213 | if (strlen($this->state) > 128) { |
||
214 | throw new DtaException("请检查state参数,最多128字节"); |
||
215 | } |
||
216 | $params = Urls::toParams([ |
||
217 | 'appid' => $this->app_id, |
||
218 | 'redirect_uri' => $this->redirect_uri, |
||
219 | 'response_type' => $this->response_type, |
||
220 | 'scope' => $this->scope, |
||
221 | 'state' => $this->state |
||
222 | ]); |
||
223 | return header("Location:https://open.weixin.qq.com/connect/oauth2/authorize?$params#wechat_redirect"); |
||
224 | } |
||
225 | |||
226 | /** |
||
227 | * 通过code换取网页授权access_token |
||
228 | * @param string $code |
||
229 | * @param bool $is |
||
230 | * @return array|bool|mixed|string |
||
231 | * @throws DtaException |
||
232 | */ |
||
233 | public function accessToken(string $code, bool $is = true) |
||
234 | { |
||
235 | if (empty($this->app_id) || empty($this->app_secret)) { |
||
236 | $this->getConfig(); |
||
237 | } |
||
238 | if (empty($this->app_id)) { |
||
239 | throw new DtaException('请检查app_id参数'); |
||
240 | } |
||
241 | if (empty($this->app_secret)) { |
||
242 | throw new DtaException('请检查app_secret参数'); |
||
243 | } |
||
244 | return HttpService::instance() |
||
245 | ->url("https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->app_id}&secret={$this->app_secret}&code={$code}&grant_type={$this->grant_type}") |
||
246 | ->toArray($is); |
||
247 | } |
||
248 | |||
249 | /** |
||
250 | * 刷新access_token(如果需要) |
||
251 | * @param string $refreshToken |
||
252 | * @param bool $is |
||
253 | * @return array|bool|mixed|string |
||
254 | * @throws DtaException |
||
255 | */ |
||
256 | public function refreshToken(string $refreshToken, bool $is = true) |
||
257 | { |
||
258 | if (empty($this->app_id)) { |
||
259 | $this->getConfig(); |
||
260 | } |
||
261 | if (empty($this->app_id)) { |
||
262 | throw new DtaException('请检查app_id参数'); |
||
263 | } |
||
264 | $this->grant_type = "refresh_token"; |
||
265 | return HttpService::instance() |
||
266 | ->url("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid={$this->app_id}&grant_type={$this->grant_type}&refresh_token={$refreshToken}") |
||
267 | ->toArray($is); |
||
268 | } |
||
269 | |||
270 | /** |
||
271 | * 拉取用户信息(需scope为 snsapi_userinfo) |
||
272 | * @param string $accessToken |
||
273 | * @param string $openid |
||
274 | * @param string $lang |
||
275 | * @param bool $is |
||
276 | * @return array|bool|mixed|string |
||
277 | */ |
||
278 | public function useInfo(string $accessToken, string $openid, $lang = "zh_CN", bool $is = true) |
||
279 | { |
||
280 | if (empty($this->app_id) || empty($this->app_secret)) { |
||
281 | $this->getConfig(); |
||
282 | } |
||
283 | return HttpService::instance() |
||
284 | ->url("https://api.weixin.qq.com/sns/userinfo?access_token={$accessToken}&openid={$openid}&lang={$lang}") |
||
285 | ->toArray($is); |
||
286 | } |
||
287 | |||
288 | /** |
||
289 | * 检验授权凭证(access_token)是否有效 |
||
290 | * @param string $accessToken |
||
291 | * @param string $openid |
||
292 | * @param bool $is |
||
293 | * @return array|bool|mixed|string |
||
294 | */ |
||
295 | public function auth(string $accessToken, string $openid, bool $is = true) |
||
296 | { |
||
297 | if (empty($this->app_id) || empty($this->app_secret)) { |
||
298 | $this->getConfig(); |
||
299 | } |
||
300 | return HttpService::instance() |
||
301 | ->url("https://api.weixin.qq.com/sns/auth?access_token={$accessToken}&openid={$openid}") |
||
302 | ->toArray($is); |
||
303 | } |
||
304 | |||
305 | /** |
||
306 | * 分享 |
||
307 | * @param string $url |
||
308 | * @return array |
||
309 | * @throws DbException |
||
310 | * @throws DtaException |
||
311 | * @throws \Exception |
||
312 | */ |
||
313 | public function share($url = '') |
||
314 | { |
||
315 | if (empty($this->app_id)) { |
||
316 | $this->getConfig(); |
||
317 | } |
||
318 | if (empty($this->app_id)) { |
||
319 | throw new DtaException('请检查app_id参数'); |
||
320 | } |
||
321 | // 获取数据 |
||
322 | $accessToken = $this->getAccessToken(); |
||
323 | if (!isset($accessToken['access_token'])) { |
||
324 | throw new DtaException("获取access_token错误," . $accessToken['errmsg']); |
||
325 | } |
||
326 | $res = HttpService::instance() |
||
327 | ->url("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$accessToken['access_token']}&type=jsapi") |
||
328 | ->toArray(); |
||
329 | if (!empty($res['errcode'])) { |
||
330 | // 获取数据 |
||
331 | $accessToken = $this->getAccessToken(); |
||
332 | if (!isset($accessToken['access_token'])) { |
||
333 | throw new DtaException("获取access_token错误," . $accessToken['errmsg']); |
||
334 | } |
||
335 | $res = HttpService::instance() |
||
336 | ->url("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$accessToken['access_token']}&type=jsapi") |
||
337 | ->toArray(); |
||
338 | if (!empty($res['errcode'])) { |
||
339 | throw new DtaException('accessToken已过期'); |
||
340 | } |
||
341 | } |
||
342 | if (empty($url)) { |
||
343 | // 注意 URL 一定要动态获取,不能 hardcode. |
||
344 | $protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] === 443) ? "https://" : "http://"; |
||
345 | $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; |
||
346 | } |
||
347 | $timestamp = time(); |
||
348 | $nonceStr = $this->createNonceStr(); |
||
349 | // 获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。 |
||
350 | $jsapiTicket = $res['ticket']; |
||
351 | // 这里参数的顺序要按照 key 值 ASCII 码升序排序 |
||
352 | $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"; |
||
353 | return [ |
||
354 | "appId" => $this->app_id, |
||
355 | "nonceStr" => $nonceStr, |
||
356 | "timestamp" => $timestamp, |
||
357 | "url" => $url, |
||
358 | "signature" => sha1($string), |
||
359 | "rawString" => $string |
||
360 | ]; |
||
361 | } |
||
362 | |||
363 | /** |
||
364 | * @param int $length |
||
365 | * @return string |
||
366 | * @throws \Exception |
||
367 | */ |
||
368 | private function createNonceStr($length = 16): string |
||
369 | { |
||
370 | $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; |
||
371 | $str = ""; |
||
372 | for ($i = 0; $i < $length; $i++) { |
||
373 | $str .= $chars[random_int(0, strlen($chars) - 1)]; |
||
374 | } |
||
375 | return $str; |
||
376 | } |
||
377 | |||
378 | /** |
||
379 | * 生成二维码 |
||
380 | * @param array $data |
||
381 | * @return array|bool|mixed|string |
||
382 | * @throws DbException |
||
383 | * @throws DtaException |
||
384 | */ |
||
385 | public function qrCode(array $data) |
||
386 | { |
||
387 | // 获取数据 |
||
388 | $accessToken = $this->getAccessToken(); |
||
389 | return HttpService::instance() |
||
390 | ->url("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={$accessToken['access_token']}") |
||
391 | ->data($data) |
||
392 | ->post() |
||
393 | ->toArray(); |
||
394 | } |
||
395 | |||
396 | /** |
||
397 | * 发送模板消息 |
||
398 | * @param array $data |
||
399 | * @return array|bool|mixed|string |
||
400 | * @throws DbException |
||
401 | * @throws DtaException |
||
402 | */ |
||
403 | public function messageTemplateSend(array $data = []) |
||
404 | { |
||
405 | // 获取数据 |
||
406 | $accessToken = $this->getAccessToken(); |
||
407 | $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$accessToken['access_token']}"; |
||
408 | return HttpService::instance() |
||
409 | ->url($url) |
||
410 | ->data($data) |
||
411 | ->toArray(); |
||
412 | } |
||
413 | |||
414 | /** |
||
415 | * 设置所属行业 |
||
416 | * https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html#0 |
||
417 | * @param string $access_token |
||
418 | * @param array $data |
||
419 | * @return bool|mixed|string |
||
420 | * @throws DbException |
||
421 | * @throws DtaException |
||
422 | */ |
||
423 | public function setIndustry(string $access_token, array $data = []) |
||
424 | { |
||
425 | // 获取数据 |
||
426 | $accessToken = $this->getAccessToken(); |
||
427 | $url = "https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token={$accessToken['access_token']}"; |
||
428 | return HttpService::instance() |
||
429 | ->url($url) |
||
430 | ->data($data) |
||
431 | ->toArray(); |
||
432 | } |
||
433 | |||
434 | /** |
||
435 | * 将一条长链接转成短链接 |
||
436 | * @param string $long_url |
||
437 | * @return bool |
||
438 | * @throws DbException |
||
439 | * @throws DtaException |
||
440 | */ |
||
441 | public function shortUrl(string $long_url) |
||
442 | { |
||
443 | // 获取数据 |
||
444 | $accessToken = $this->getAccessToken(); |
||
445 | $url = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token={$accessToken['access_token']}"; |
||
446 | return HttpService::instance() |
||
447 | ->url($url) |
||
448 | ->data([ |
||
449 | 'action' => 'long2short', |
||
450 | 'long_url' => $long_url |
||
451 | ]) |
||
452 | ->toArray(); |
||
453 | } |
||
454 | |||
455 | /** |
||
456 | * 连Wi-Fi完成页跳转小程序 |
||
457 | * https://developers.weixin.qq.com/doc/offiaccount/WiFi_via_WeChat/WiFi_mini_programs.html |
||
458 | * @param array $data |
||
459 | * @return array|bool|mixed|string |
||
460 | * @throws DbException |
||
461 | * @throws DtaException |
||
462 | */ |
||
463 | public function fiNihPageSet(array $data = []) |
||
464 | { |
||
465 | // 获取数据 |
||
466 | $accessToken = $this->getAccessToken(); |
||
467 | $url = "https://api.weixin.qq.com/bizwifi/finishpage/set?access_token={$accessToken['access_token']}"; |
||
468 | return HttpService::instance() |
||
469 | ->url($url) |
||
470 | ->post() |
||
471 | ->data($data) |
||
472 | ->toArray(); |
||
473 | } |
||
474 | |||
475 | /** |
||
476 | * 自定义菜单 获取自定义菜单配置 |
||
477 | * https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Getting_Custom_Menu_Configurations.html |
||
478 | * @return array|bool|mixed|string |
||
479 | * @throws DbException |
||
480 | * @throws DtaException |
||
481 | */ |
||
482 | public function menuGet() |
||
483 | { |
||
484 | // 获取数据 |
||
485 | $accessToken = $this->getAccessToken(); |
||
486 | $url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token={$accessToken['access_token']}"; |
||
487 | return HttpService::instance() |
||
488 | ->url($url) |
||
489 | ->toArray(); |
||
490 | } |
||
491 | |||
492 | /** |
||
493 | * 自定义菜单 创建个性化菜单 |
||
494 | * https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Personalized_menu_interface.html |
||
495 | * @param array $data |
||
496 | * @return array|bool|mixed|string |
||
497 | * @throws DbException |
||
498 | * @throws DtaException |
||
499 | */ |
||
500 | public function menuAddConditional(array $data = []) |
||
501 | { |
||
502 | // 获取数据 |
||
503 | $accessToken = $this->getAccessToken(); |
||
504 | $url = "https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token={$accessToken['access_token']}"; |
||
505 | return HttpService::instance() |
||
506 | ->url($url) |
||
507 | ->post() |
||
508 | ->data($data) |
||
509 | ->toArray(); |
||
510 | } |
||
511 | |||
512 | /** |
||
513 | * 自定义菜单 删除个性化菜单 |
||
514 | * https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Personalized_menu_interface.html |
||
515 | * @param array $data |
||
516 | * @return array|bool|mixed|string |
||
517 | * @throws DbException |
||
518 | * @throws DtaException |
||
519 | */ |
||
520 | public function menuDelConditional(array $data = []) |
||
521 | { |
||
522 | // 获取数据 |
||
523 | $accessToken = $this->getAccessToken(); |
||
524 | $url = "https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token={$accessToken['access_token']}"; |
||
525 | return HttpService::instance() |
||
526 | ->url($url) |
||
527 | ->post() |
||
528 | ->data($data) |
||
529 | ->toArray(); |
||
530 | } |
||
531 | |||
532 | /** |
||
533 | * 自定义菜单 测试个性化菜单匹配结果 |
||
534 | * https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Personalized_menu_interface.html |
||
535 | * @param array $data |
||
536 | * @return array|bool|mixed|string |
||
537 | * @throws DbException |
||
538 | * @throws DtaException |
||
539 | */ |
||
540 | public function menuTryMatch(array $data = []) |
||
550 | } |
||
551 | |||
552 | /** |
||
553 | * 自定义菜单 删除接口 |
||
554 | * https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Deleting_Custom-Defined_Menu.html |
||
555 | * @return array|bool|mixed|string |
||
556 | * @throws DbException |
||
557 | * @throws DtaException |
||
558 | */ |
||
559 | public function menuDelete() |
||
567 | } |
||
568 | |||
569 | /** |
||
570 | * 自定义菜单 查询接口 |
||
571 | * https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Querying_Custom_Menus.html |
||
572 | * @return array|bool|mixed|string |
||
573 | * @throws DbException |
||
574 | * @throws DtaException |
||
575 | */ |
||
576 | public function getCurrentSelfmenuInfo() |
||
577 | { |
||
578 | // 获取数据 |
||
579 | $accessToken = $this->getAccessToken(); |
||
580 | $url = "https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token={$accessToken['access_token']}"; |
||
581 | return HttpService::instance() |
||
582 | ->url($url) |
||
583 | ->toArray(); |
||
584 | } |
||
585 | |||
586 | /** |
||
587 | * 自定义菜单 创建接口 |
||
588 | * https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.html |
||
589 | * @param array $data |
||
590 | * @return array|bool|mixed|string |
||
591 | * @throws DbException |
||
592 | * @throws DtaException |
||
593 | */ |
||
594 | public function menuCreate(array $data = []) |
||
595 | { |
||
596 | // 获取数据 |
||
597 | $accessToken = $this->getAccessToken(); |
||
598 | $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={$accessToken['access_token']}"; |
||
599 | return HttpService::instance() |
||
600 | ->url($url) |
||
601 | ->post() |
||
602 | ->data($data) |
||
603 | ->toArray(); |
||
604 | } |
||
605 | |||
606 | /** |
||
607 | * 获取access_token信息 |
||
608 | * @return array|bool|mixed|string|string[] |
||
609 | * @throws DbException |
||
610 | * @throws DtaException |
||
611 | */ |
||
612 | private function getAccessToken() |
||
613 | { |
||
614 | if (empty($this->cache) || empty($this->app_id) || empty($this->app_secret)) { |
||
615 | $this->getConfig(); |
||
616 | } |
||
617 | if (empty($this->cache)) { |
||
618 | throw new DtaException('请检查cache参数'); |
||
619 | } |
||
620 | if (empty($this->app_id)) { |
||
621 | throw new DtaException('请检查app_id参数'); |
||
622 | } |
||
623 | if (empty($this->app_secret)) { |
||
624 | throw new DtaException('请检查app_secret参数'); |
||
625 | } |
||
626 | |||
627 | $this->grant_type = "client_credential"; |
||
628 | if ($this->cache === "file") { |
||
629 | // 文件名 |
||
630 | $file = "{$this->app->getRootPath()}runtime/{$this->app_id}_access_token.json"; |
||
631 | // 获取数据 |
||
632 | $accessToken = file_exists($file) ? json_decode(file_get_contents($file), true) : []; |
||
633 | if (empty($accessToken) || !is_array($accessToken)) { |
||
634 | $accessToken = [ |
||
635 | 'access_token' => '', |
||
636 | 'expires_in' => '', |
||
637 | 'expires_time' => '', |
||
638 | ]; |
||
639 | } |
||
640 | if (empty($accessToken['expires_time'])) { |
||
641 | // 文件不存在 |
||
642 | $accessToken_res = HttpService::instance() |
||
643 | ->url("https://api.weixin.qq.com/cgi-bin/token?grant_type={$this->grant_type}&appid={$this->app_id}&secret={$this->app_secret}") |
||
644 | ->toArray(); |
||
645 | $accessToken_res['expires_time'] = time() + 6000; |
||
646 | file_put_contents($file, json_encode($accessToken_res, JSON_UNESCAPED_UNICODE)); |
||
647 | $accessToken = $accessToken_res; |
||
648 | } else if (!isset($accessToken['access_token'])) { |
||
649 | // 内容不存在 |
||
650 | $accessToken_res = HttpService::instance() |
||
651 | ->url("https://api.weixin.qq.com/cgi-bin/token?grant_type={$this->grant_type}&appid={$this->app_id}&secret={$this->app_secret}") |
||
652 | ->toArray(); |
||
653 | $accessToken_res['expires_time'] = time() + 6000; |
||
654 | file_put_contents($file, json_encode($accessToken_res, JSON_UNESCAPED_UNICODE)); |
||
655 | $accessToken = $accessToken_res; |
||
656 | } else if ($accessToken['expires_time'] <= time()) { |
||
657 | $accessToken_res = HttpService::instance() |
||
658 | ->url("https://api.weixin.qq.com/cgi-bin/token?grant_type={$this->grant_type}&appid={$this->app_id}&secret={$this->app_secret}") |
||
659 | ->toArray(); |
||
660 | $accessToken_res['expires_time'] = time() + 6000; |
||
661 | file_put_contents($file, json_encode($accessToken_res, JSON_UNESCAPED_UNICODE)); |
||
662 | $accessToken = $accessToken_res; |
||
663 | } |
||
664 | if (isset($accessToken['access_token'])) { |
||
665 | $judge = HttpService::instance() |
||
666 | ->url("https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token={$accessToken['access_token']}") |
||
667 | ->toArray(); |
||
668 | if (!isset($judge['ip_list'])) { |
||
669 | $accessToken_res = HttpService::instance() |
||
670 | ->url("https://api.weixin.qq.com/cgi-bin/token?grant_type={$this->grant_type}&appid={$this->app_id}&secret={$this->app_secret}") |
||
671 | ->toArray(); |
||
672 | $accessToken_res['expires_time'] = time() + 6000; |
||
673 | file_put_contents($file, json_encode($accessToken_res, JSON_UNESCAPED_UNICODE)); |
||
674 | $accessToken = $accessToken_res; |
||
675 | } |
||
676 | } else { |
||
677 | $accessToken_res = HttpService::instance() |
||
678 | ->url("https://api.weixin.qq.com/cgi-bin/token?grant_type={$this->grant_type}&appid={$this->app_id}&secret={$this->app_secret}") |
||
679 | ->toArray(); |
||
680 | $accessToken_res['expires_time'] = time() + 6000; |
||
681 | file_put_contents($file, json_encode($accessToken_res, JSON_UNESCAPED_UNICODE)); |
||
682 | $accessToken = $accessToken_res; |
||
683 | } |
||
684 | return $accessToken; |
||
685 | } |
||
686 | |||
687 | if ($this->cache === "mysql") { |
||
688 | $access_token = []; |
||
689 | // 文件名 |
||
690 | $file = "{$this->app_id}_access_token"; |
||
691 | // 获取数据 |
||
692 | $cache_mysql_value = dtacache($file); |
||
693 | if (!empty($cache_mysql_value)) { |
||
694 | $access_token['access_token'] = $cache_mysql_value; |
||
695 | } else { |
||
696 | // 获取远程Token |
||
697 | $accessToken_res = HttpService::instance() |
||
698 | ->url("https://api.weixin.qq.com/cgi-bin/token?grant_type={$this->grant_type}&appid={$this->app_id}&secret={$this->app_secret}") |
||
699 | ->toArray(); |
||
700 | // 保存到数据库 |
||
701 | dtacache($file, $accessToken_res['access_token'], 6000); |
||
702 | $access_token['access_token'] = $accessToken_res['access_token']; |
||
703 | } |
||
704 | // 判断token是否可以使用 |
||
705 | $judge = HttpService::instance() |
||
706 | ->url("https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token={$access_token['access_token']}") |
||
707 | ->toArray(); |
||
708 | if (!isset($judge['ip_list'])) { |
||
709 | $accessToken_res = HttpService::instance() |
||
710 | ->url("https://api.weixin.qq.com/cgi-bin/token?grant_type={$this->grant_type}&appid={$this->app_id}&secret={$this->app_secret}") |
||
711 | ->toArray(); |
||
712 | dtacache($file, $accessToken_res['access_token'], 6000); |
||
713 | $access_token['access_token'] = $accessToken_res['access_token']; |
||
714 | } |
||
715 | return $access_token; |
||
716 | } |
||
717 | |||
718 | throw new DtaException("驱动方式错误"); |
||
719 | } |
||
720 | |||
721 | /** |
||
722 | * 微信支付 |
||
723 | * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1 |
||
724 | * @param array $array |
||
725 | * @return bool|string |
||
726 | */ |
||
727 | public function payUnfIedOrder(array $array) |
||
728 | { |
||
729 | $array['appid'] = $this->app_id; |
||
730 | $array['mch_id'] = $this->mch_id; |
||
731 | $array['nonce_str'] = Randoms::generate(32, 3); |
||
732 | $array['sign_type'] = 'HMAC-SHA256'; |
||
733 | $array['sign'] = $this->paySign($array); |
||
734 | $res = $this->postXmlCurl(Xmls::toXml($array)); |
||
735 | return Xmls::toArray($res); |
||
736 | } |
||
737 | |||
738 | /** |
||
739 | * 微信内H5调起支付 |
||
740 | * @param string $prepay_id |
||
741 | * @return array |
||
742 | */ |
||
743 | public function h5Pay(string $prepay_id) |
||
752 | } |
||
753 | |||
754 | /** |
||
755 | * 生成支付签名 |
||
756 | * @param array $array 参与签名的内容组成的数组 |
||
757 | * @param bool $hmacsha256 是否使用 HMAC-SHA256算法,否则使用MD5 |
||
758 | * @return string |
||
759 | */ |
||
760 | private function paySign(array $array, bool $hmacsha256 = true): string |
||
761 | { |
||
762 | // 排序 |
||
763 | ksort($array); |
||
764 | // 转成字符串 |
||
765 | $stringA = Urls::toParams($array); |
||
766 | // 在字符串接商户支付秘钥 |
||
767 | $stringSignTemp = "{$stringA}&key=" . $this->mch_key; |
||
768 | //步骤四:MD5或HMAC-SHA256C加密 |
||
769 | if ($hmacsha256) { |
||
770 | $str = hash_hmac("sha256", $stringSignTemp, $this->mch_key); |
||
771 | } else { |
||
772 | $str = md5($stringSignTemp); |
||
773 | } |
||
774 | //符转大写 |
||
775 | return strtoupper($str); |
||
776 | } |
||
777 | |||
778 | /** |
||
779 | * @param $xml |
||
780 | * @return bool|string |
||
781 | */ |
||
782 | private function postXmlCurl($xml) |
||
811 | } |
||
812 | } |
||
813 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.