| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 | <?php/** * Created by PhpStorm. * User: tandunzhao * Date: 2017/12/4 * Time: 上午11:49 */namespace App\Modules\Book\Services;use Redis;use EasyWeChat\Foundation\Application;class ChapterShareWechatConfigService{    private $appId;    private $appSecret;    private $accessToken;    private $jsapiTicket;    public function __construct($appId, $appSecret)    {        $this->appId = $appId ? $appId : env('JS_AppID');        $this->appSecret = $appSecret ? $appSecret : env('JS_AppSecret');        //\Log::info('appId:'.($this->appId).'appSecret:'.($this->appSecret));    }    public function getSignPackage($url = '', $is_force = true, $only_cache = false)    {        $jsapiTicket = $this->getJsApiTicket($is_force, $only_cache);        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";        $url = $url ? $url : "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";        $timestamp = time();        $nonceStr = $this->createNonceStr();        // 这里参数的顺序要按照 key 值 ASCII 码升序排序        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url";        \Log::info($string);        $signature = sha1($string);        $signPackage = array(            "appId" => $this->appId,            "nonceStr" => $nonceStr,            "timestamp" => $timestamp,            "url" => $url,            "signature" => $signature,            "rawString" => $string        );        return $signPackage;    }    private function createNonceStr($length = 16)    {        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";        $str = "";        for ($i = 0; $i < $length; $i++) {            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);        }        return $str;    }    private function getJsApiTicket($is_force = false, $only_cache = true)    {        // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例        $data = unserialize(Redis::get(($this->appId) . "jsapi_ticket"));        if (empty($data) || $data['expire_time'] < time()) {            $accessToken = $this->getToken($is_force, $only_cache);            \Log::info(($this->appId) . ':' . $accessToken);            // 如果是企业号用以下 URL 获取 ticket            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token={$accessToken}";            $res = json_decode($this->httpGet($url));            $ticket = $res->ticket;            if ($ticket) {                $data['expire_time'] = time() + 7000;                $data['jsapi_ticket'] = $ticket;                Redis::setex(($this->appId) . "jsapi_ticket", 7000, serialize($data));            }        } else {            $ticket = $data['jsapi_ticket'];        }        \Log::info(($this->appId) . ':' . 'jsapi_tiket:' . $ticket);        return $ticket;    }    private function httpGet($url)    {        $curl = curl_init();        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);        curl_setopt($curl, CURLOPT_TIMEOUT, 3);        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);        curl_setopt($curl, CURLOPT_URL, $url);        $res = curl_exec($curl);        curl_close($curl);        return $res;    }    /**     * 获取access token     *     * @param string $is_force     * @return unknown|unknown|mixed|object|boolean     */    public function getToken($is_force = true, $only_cache = true)    {        if ($is_force == false) {            $data = unserialize(Redis::get(($this->appId) . "access_token"));            if ($data) {                if (is_array($data) && $data['expire_time'] > time()) {                    $access_token = $data['access_token'];                    return $access_token;                } else if (is_string($data)) {                    $access_token = $data;                    return $access_token;                }            }            if ($only_cache) {                // 非强制获取access_token,cache没有就直接返回false,防止获取access_token的接口在高并发下被滥用                return false;            }        }        $appId = $this->appId;        $appSecret = $this->appSecret;        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appId . '&secret=' . $appSecret;        $rs1 = self::https_request($url);        \Log::info(($this->appId) . 'get_token-' . $rs1);        if ($rs1) {            $rs = json_decode($rs1, true);            if (is_array($rs) && $rs['access_token']) {                $access_token = $rs['access_token'];                $expires_in = intval($rs['expires_in'], 10);                if ($expires_in <= 0) {                    $expires_in = 5;                } else if ($expires_in >= 7200) {                    $expires_in = 7000;                }                $data = array();                $data['expire_time'] = time() + $expires_in;                $data['access_token'] = $access_token;                Redis::setex(($this->appId) . 'access_token', $expires_in, serialize($data));                return $access_token;            } else {                $content = "get access token error:" . $rs1;                \Log::info(($this->appId) . $content);            }        } else {            $content = "get access token error:" . $rs1;            \Log::info(($this->appId) . $content);        }        return false;    }    /**     * 抓https数据     *     * @param unknown $url     * @param string $data     * @param string $timeout     */    static function https_request($url, $data = null, $timeout = 5000)    {        $curl = curl_init();        curl_setopt($curl, CURLOPT_URL, $url);        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);        if (!empty($data)) {            curl_setopt($curl, CURLOPT_POST, 1);            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);        }        if ($timeout) {            curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);        }        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);        $output = curl_exec($curl);        if ($output === false) {            \Log::error('Curl error: ' . curl_error($curl) . ". url:" . $url);        }        curl_close($curl);        return $output;    }    public function setAccessToken($token)    {        $this->accessToken = $token;    }    public function requestAccessToken()    {        $data = unserialize(Redis::get(($this->appId) . "access_token"));        if ($data) {            if (is_array($data) && $data['expire_time'] > time()) {                $access_token = $data['access_token'];                $this->setAccessToken($access_token);                return true;            } else if (is_string($data)) {                $access_token = $data;                $this->setAccessToken($access_token);                return true;            }        }        $appId = $this->appId;        $appSecret = $this->appSecret;        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appId . '&secret=' . $appSecret;        $rs1 = self::https_request($url);        \Log::info(($this->appId) . 'get_token-' . $rs1);        if ($rs1) {            $rs = json_decode($rs1, true);            if (is_array($rs) && $rs['access_token']) {                $access_token = $rs['access_token'];                $expires_in = intval($rs['expires_in'], 10);                if ($expires_in <= 0) {                    $expires_in = 5;                } else if ($expires_in >= 7200) {                    $expires_in = 7000;                }                $data = array();                $data['expire_time'] = time() + $expires_in;                $data['access_token'] = $access_token;                Redis::setex(($this->appId) . 'access_token', $expires_in, serialize($data));                $this->setAccessToken($access_token);                return true;            } else {                $content = "get access token error:" . $rs1;                \Log::info(($this->appId) . $content);                return false;            }        } else {            $content = "get access token error:" . $rs1;            \Log::info(($this->appId) . $content);            return false;        }    }    public function  setJsapiTicket($ticket){        $this->jsapiTicket = $ticket;    }    public function requestJsApiTicket()    {        // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例        $data = unserialize(Redis::get(($this->appId) . "jsapi_ticket"));        if (empty($data) || $data['expire_time'] < time()) {            $accessToken = $this->accessToken;            \Log::info(($this->appId) . ':' . $accessToken);            // 如果是企业号用以下 URL 获取 ticket            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token={$accessToken}";            $res = json_decode($this->httpGet($url));            $ticket = $res->ticket;            if ($ticket) {                $data['expire_time'] = time() + 7000;                $data['jsapi_ticket'] = $ticket;                Redis::setex(($this->appId) . "jsapi_ticket", 7000, serialize($data));                $this->setJsapiTicket($ticket);                return true;            }            return false;        } else {            $ticket = $data['jsapi_ticket'];            $this->setJsapiTicket($ticket);            return true;        }    }    public function getJssdkConfig($url)    {        $jsapiTicket = $this->jsapiTicket;        $timestamp = time();        $nonceStr = $this->createNonceStr();        // 这里参数的顺序要按照 key 值 ASCII 码升序排序        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url";        $signature = sha1($string);        $signPackage = array(            "appId" => $this->appId,            "nonceStr" => $nonceStr,            "timestamp" => $timestamp,            "url" => $url,            "signature" => $signature,            "rawString" => $string        );        return $signPackage;    }    public static function getConfig($url)    {        $options = [            'debug' => false,            'app_id' => env('JS_AppId'),            'secret' => env('JS_AppSecret'),            //'token'  => 'easywechat',            // 'aes_key' => null, // 可选            'log' => [                'level' => 'debug',                'file' => storage_path('easywechat.log'), // XXX: 绝对路径!!!!            ],        ];        $app = new Application($options);        $js = $app->js;        $js->setUrl($url);        $config = $js->Config([            'onMenuShareTimeline',            'onMenuShareAppMessage',            'onMenuShareQQ',            'onMenuShareWeibo',            'showOptionMenu',            'hideOptionMenu',            'hideMenuItems',            'hideAllNonBaseMenuItem'        ], $debug = false, $beta = false, $json = false);        return $config;    }}
 |