mirror of
				https://gitee.com/zoujingli/WeChatDeveloper.git
				synced 2025-11-04 10:52:08 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			208 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			208 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						||
 | 
						||
// +----------------------------------------------------------------------
 | 
						||
// | WeChatDeveloper
 | 
						||
// +----------------------------------------------------------------------
 | 
						||
// | 版权所有 2014~2018 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
 | 
						||
// +----------------------------------------------------------------------
 | 
						||
// | 官方网站: http://think.ctolog.com
 | 
						||
// +----------------------------------------------------------------------
 | 
						||
// | 开源协议 ( https://mit-license.org )
 | 
						||
// +----------------------------------------------------------------------
 | 
						||
// | github开源项目:https://github.com/zoujingli/WeChatDeveloper
 | 
						||
// +----------------------------------------------------------------------
 | 
						||
 | 
						||
namespace WeChat\Contracts;
 | 
						||
 | 
						||
use WeChat\Exceptions\InvalidArgumentException;
 | 
						||
use WeChat\Exceptions\InvalidResponseException;
 | 
						||
 | 
						||
/**
 | 
						||
 * Class BasicWeChat
 | 
						||
 * @package WeChat\Contracts
 | 
						||
 */
 | 
						||
class BasicWeChat
 | 
						||
{
 | 
						||
 | 
						||
    /**
 | 
						||
     * 当前微信配置
 | 
						||
     * @var DataArray
 | 
						||
     */
 | 
						||
    public $config;
 | 
						||
 | 
						||
    /**
 | 
						||
     * 访问AccessToken
 | 
						||
     * @var string
 | 
						||
     */
 | 
						||
    public $access_token = '';
 | 
						||
 | 
						||
    /**
 | 
						||
     * 当前请求方法参数
 | 
						||
     * @var array
 | 
						||
     */
 | 
						||
    private $currentMethod = [];
 | 
						||
 | 
						||
    /**
 | 
						||
     * 当前模式
 | 
						||
     * @var bool
 | 
						||
     */
 | 
						||
    private $isTry = false;
 | 
						||
 | 
						||
    /**
 | 
						||
     * 注册代替函数
 | 
						||
     * @var string
 | 
						||
     */
 | 
						||
    private $GetAccessTokenCallback;
 | 
						||
 | 
						||
    /**
 | 
						||
     * BasicWeChat constructor.
 | 
						||
     * @param array $options
 | 
						||
     */
 | 
						||
    public function __construct(array $options)
 | 
						||
    {
 | 
						||
        if (empty($options['appid'])) {
 | 
						||
            throw new InvalidArgumentException("Missing Config -- [appid]");
 | 
						||
        }
 | 
						||
        if (empty($options['appsecret'])) {
 | 
						||
            throw new InvalidArgumentException("Missing Config -- [appsecret]");
 | 
						||
        }
 | 
						||
        if (isset($options['GetAccessTokenCallback']) && is_callable($options['GetAccessTokenCallback'])) {
 | 
						||
            $this->GetAccessTokenCallback = $options['GetAccessTokenCallback'];
 | 
						||
        }
 | 
						||
        if (!empty($options['cache_path'])) {
 | 
						||
            Tools::$cache_path = $options['cache_path'];
 | 
						||
        }
 | 
						||
        $this->config = new DataArray($options);
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 获取访问accessToken
 | 
						||
     * @return string
 | 
						||
     * @throws \WeChat\Exceptions\InvalidResponseException
 | 
						||
     * @throws \WeChat\Exceptions\LocalCacheException
 | 
						||
     */
 | 
						||
    public function getAccessToken()
 | 
						||
    {
 | 
						||
        if (!empty($this->access_token)) {
 | 
						||
            return $this->access_token;
 | 
						||
        }
 | 
						||
        $cache = $this->config->get('appid') . '_access_token';
 | 
						||
        $this->access_token = Tools::getCache($cache);
 | 
						||
        if (!empty($this->access_token)) {
 | 
						||
            return $this->access_token;
 | 
						||
        }
 | 
						||
        // 处理开放平台授权公众号获取AccessToken
 | 
						||
        if (!empty($this->GetAccessTokenCallback) && is_callable($this->GetAccessTokenCallback)) {
 | 
						||
            $this->access_token = call_user_func_array($this->GetAccessTokenCallback, [$this->config->get('appid'), $this]);
 | 
						||
            if (!empty($this->access_token)) {
 | 
						||
                Tools::setCache($cache, $this->access_token, 7000);
 | 
						||
            }
 | 
						||
            return $this->access_token;
 | 
						||
        }
 | 
						||
        list($appid, $secret) = [$this->config->get('appid'), $this->config->get('appsecret')];
 | 
						||
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$secret}";
 | 
						||
        $result = Tools::json2arr(Tools::get($url));
 | 
						||
        if (!empty($result['access_token'])) {
 | 
						||
            Tools::setCache($cache, $result['access_token'], 7000);
 | 
						||
        }
 | 
						||
        return $this->access_token = $result['access_token'];
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 清理删除accessToken
 | 
						||
     * @return bool
 | 
						||
     */
 | 
						||
    public function delAccessToken()
 | 
						||
    {
 | 
						||
        $this->access_token = '';
 | 
						||
        return Tools::delCache($this->config->get('appid') . '_access_token');
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 以GET获取接口数据并转为数组
 | 
						||
     * @param string $url 接口地址
 | 
						||
     * @return array
 | 
						||
     * @throws \WeChat\Exceptions\InvalidResponseException
 | 
						||
     */
 | 
						||
    protected function httpGetForJson($url)
 | 
						||
    {
 | 
						||
        try {
 | 
						||
            return Tools::json2arr(Tools::get($url));
 | 
						||
        } catch (InvalidResponseException $e) {
 | 
						||
            if (!$this->isTry && in_array($e->getCode(), ['40014', '40001', '41001', '42001'])) {
 | 
						||
                $this->delAccessToken();
 | 
						||
                $this->isTry = true;
 | 
						||
                return call_user_func_array([$this, $this->currentMethod['method']], $this->currentMethod['arguments']);
 | 
						||
            }
 | 
						||
            throw new InvalidResponseException($e->getMessage(), $e->getCode());
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 以POST获取接口数据并转为数组
 | 
						||
     * @param string $url 接口地址
 | 
						||
     * @param array $data 请求数据
 | 
						||
     * @param bool $buildToJson
 | 
						||
     * @return array
 | 
						||
     * @throws \WeChat\Exceptions\InvalidResponseException
 | 
						||
     */
 | 
						||
    protected function httpPostForJson($url, array $data, $buildToJson = true)
 | 
						||
    {
 | 
						||
        try {
 | 
						||
            return Tools::json2arr(Tools::post($url, $buildToJson ? Tools::arr2json($data) : $data));
 | 
						||
        } catch (InvalidResponseException $e) {
 | 
						||
            if (!$this->isTry && in_array($e->getCode(), ['40014', '40001', '41001', '42001'])) {
 | 
						||
                [$this->delAccessToken(), $this->isTry = true];
 | 
						||
                return call_user_func_array([$this, $this->currentMethod['method']], $this->currentMethod['arguments']);
 | 
						||
            }
 | 
						||
            throw new InvalidResponseException($e->getMessage(), $e->getCode());
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 注册当前请求接口
 | 
						||
     * @param string $url 接口地址
 | 
						||
     * @param string $method 当前接口方法
 | 
						||
     * @param array $arguments 请求参数
 | 
						||
     * @return mixed
 | 
						||
     * @throws \WeChat\Exceptions\InvalidResponseException
 | 
						||
     * @throws \WeChat\Exceptions\LocalCacheException
 | 
						||
     */
 | 
						||
    protected function registerApi(&$url, $method, $arguments = [])
 | 
						||
    {
 | 
						||
        $this->currentMethod = ['method' => $method, 'arguments' => $arguments];
 | 
						||
        if (empty($this->access_token)) {
 | 
						||
            $this->access_token = $this->getAccessToken();
 | 
						||
        }
 | 
						||
        return $url = str_replace('ACCESS_TOKEN', $this->access_token, $url);
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 接口通用POST请求方法
 | 
						||
     * @param string $url 接口URL
 | 
						||
     * @param array $data POST提交接口参数
 | 
						||
     * @param bool $isBuildJson
 | 
						||
     * @return array
 | 
						||
     * @throws InvalidResponseException
 | 
						||
     * @throws \WeChat\Exceptions\LocalCacheException
 | 
						||
     */
 | 
						||
    public function callPostApi($url, array $data, $isBuildJson = true)
 | 
						||
    {
 | 
						||
        $this->registerApi($url, __FUNCTION__, func_get_args());
 | 
						||
        return $this->httpPostForJson($url, $data, $isBuildJson);
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 接口通用GET请求方法
 | 
						||
     * @param string $url 接口URL
 | 
						||
     * @return array
 | 
						||
     * @throws InvalidResponseException
 | 
						||
     * @throws \WeChat\Exceptions\LocalCacheException
 | 
						||
     */
 | 
						||
    public function callGetApi($url)
 | 
						||
    {
 | 
						||
        $this->registerApi($url, __FUNCTION__, func_get_args());
 | 
						||
        return $this->httpGetForJson($url);
 | 
						||
    }
 | 
						||
 | 
						||
} |