├── src ├── MiniProgramException.php ├── Api │ ├── MediaUpload.php │ ├── MediaGet.php │ ├── AccessToken.php │ ├── MessageWxOpenTemplateSend.php │ ├── CreateQrCode.php │ ├── JsCodeToSession.php │ ├── MessageCustomSend.php │ └── BaseApi.php ├── EncryptedData.php ├── Config.php ├── MiniProgram.php └── CurlRequest.php ├── .gitignore ├── composer.json ├── composer.lock ├── LICENSE └── README.md /src/MiniProgramException.php: -------------------------------------------------------------------------------- 1 | $this->accessToken, 22 | 'type' => '', 23 | ]; 24 | // todo:Form 25 | } 26 | 27 | 28 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yingouqlj/wechat-mini-program-lite", 3 | "description": "微信小程序sdk,wechat miniprogram sdk.(前面堆一下关键字而已.这个包主要是只有微信小程序,轻巧无负担,无需安装各种依赖包.", 4 | "keywords": [ 5 | "wechat", 6 | "weixin", 7 | "weixin-sdk", 8 | "miniprogram" 9 | ], 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "yingou", 14 | "email": "yingouqlj@gmail.com" 15 | } 16 | ], 17 | "require": { 18 | "php":">=5.5.0" 19 | }, 20 | "minimum-stability" : "dev", 21 | "autoload": { 22 | "psr-4": { 23 | "Yingou\\MiniProgram\\": "src/" 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "189f5fa9cbd6bf6420b0dbaa3c037b54", 8 | "packages": [], 9 | "packages-dev": [], 10 | "aliases": [], 11 | "minimum-stability": "dev", 12 | "stability-flags": [], 13 | "prefer-stable": false, 14 | "prefer-lowest": false, 15 | "platform": { 16 | "php": ">=5.5.0" 17 | }, 18 | "platform-dev": [] 19 | } 20 | -------------------------------------------------------------------------------- /src/Api/MediaGet.php: -------------------------------------------------------------------------------- 1 | $this->accessToken, 22 | 'media_id' => $mediaId, 23 | ]; 24 | $result = $this->query(self::API, $params); 25 | 26 | return $result; 27 | } 28 | 29 | 30 | } -------------------------------------------------------------------------------- /src/Api/AccessToken.php: -------------------------------------------------------------------------------- 1 | $this->grant_type, 24 | 'appid' => $this->appId, 25 | 'secret' => $this->secret, 26 | ]; 27 | return $this->get($params); 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/Api/MessageWxOpenTemplateSend.php: -------------------------------------------------------------------------------- 1 | toUser = $openId; 27 | return $this; 28 | } 29 | 30 | 31 | } -------------------------------------------------------------------------------- /src/EncryptedData.php: -------------------------------------------------------------------------------- 1 | $path, 29 | 'width' => $width, 30 | ]; 31 | return $this->query(self::API . '?access_token=' . $this->accessToken, $params, 'post'); 32 | 33 | } 34 | 35 | 36 | } -------------------------------------------------------------------------------- /src/Api/JsCodeToSession.php: -------------------------------------------------------------------------------- 1 | jsCode = $code; 28 | $params = [ 29 | 'appid' => $this->appId, 30 | 'secret' => $this->secret, 31 | 'js_code' => $this->jsCode, 32 | 'grant_type' => $this->grantType, 33 | ]; 34 | return $this->get($params); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 钱礼骏 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # miniProgram-lite 2 | 微信小程序php后端接口轻量版 3 | 4 | 5 | ####初衷: 6 | 好用的微信SDK一大堆,已经没有自己写了。 7 | 但是好用的SDK大而全,依赖也大。对于业务很小的应用着实有点浪费。 8 | 当时业务需求,顺势做小程序,但是实际后端的接口用量很小,所以打算用到的接口自己包一下。 9 | 再然后,就打算拆出来分享出来。 10 | 11 | ##安装: 12 | ```shell 13 | composer require yingouqlj/wechat-mini-program-lite 14 | ``` 15 | 16 | 17 | ##基本使用: 18 | 19 | ```php 20 | 'appid', 25 | 'secret' => 'secret' 26 | ]; 27 | $program=new MiniProgram($config); 28 | //创建Qrcode 29 | $program->createQrCode->create('/page?id=1',120); 30 | 31 | ``` 32 | 33 | 34 | ##建议用法: 35 | 增加个配置继承Config 36 | 在里面实现 token 的读写覆盖原有方法 37 | 38 | ```php 39 | createQrCode->create('/page?id=1',120); 55 | 56 | ``` 57 | 58 | 59 | ##接口 60 | 61 | + [获取 access_token](https://github.com/yingouqlj/MiniProgram-lite/wiki/%E8%8E%B7%E5%8F%96-access_token) 62 | + [js换取登录后的openid](https://github.com/yingouqlj/MiniProgram-lite/wiki/code-%E6%8D%A2%E5%8F%96-session_key) 63 | 64 | 65 | ####进度 66 | 先立项,慢慢完善。后面也会考虑引入其他依赖包。第一版是轻巧。 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/Config.php: -------------------------------------------------------------------------------- 1 | packageConfig('miniProgram'); 25 | } 26 | if (isset($config['appId'])) { 27 | $this->appId = $config['appId']; 28 | } 29 | if (isset($config['secret'])) { 30 | $this->secret = $config['secret']; 31 | } 32 | } 33 | 34 | /** 35 | * 覆盖这个方法写取token的实现 ,比如redis,数据库 36 | * @return $token 37 | */ 38 | public function getAccessToken() 39 | { 40 | if (!file_exists(sys_get_temp_dir() . $this->tmpFile)) { 41 | return null; 42 | } 43 | $data = json_decode(file_get_contents(sys_get_temp_dir() . $this->tmpFile), true); 44 | if ($data['expire'] > time()) { 45 | return $data['token']; 46 | } 47 | return null; 48 | } 49 | 50 | /** 51 | * 覆盖这个方法 存token,默认写临时文件 52 | * @param $token 53 | * @param int $expires 54 | * @return int 55 | */ 56 | public function setAccessToken($token, $expires = 0) 57 | { 58 | return file_put_contents(sys_get_temp_dir() . $this->tmpFile, json_encode(['token' => $token, 'expire' => (time() + $expires)])); 59 | } 60 | 61 | 62 | } -------------------------------------------------------------------------------- /src/Api/MessageCustomSend.php: -------------------------------------------------------------------------------- 1 | toUser = $openId; 27 | return $this; 28 | } 29 | 30 | public function text($content) 31 | { 32 | $this->msgType = self::SEND_CUSTOMER_MESSAGE_MSG_TYPE_TEXT; 33 | $this->text = (object)['content' => $content]; 34 | return $this->send(); 35 | } 36 | 37 | public function image($mediaId) 38 | { 39 | 40 | $this->msgType = self::SEND_CUSTOMER_MESSAGE_MSG_TYPE_IMAGE; 41 | $this->image = (object)['media_id' => $mediaId]; 42 | return $this->send(); 43 | } 44 | 45 | protected function send() 46 | { 47 | if (!$this->toUser) { 48 | throw new \Exception('no openid'); 49 | } 50 | if (!in_array($this->msgType, [self::SEND_CUSTOMER_MESSAGE_MSG_TYPE_TEXT, self::SEND_CUSTOMER_MESSAGE_MSG_TYPE_IMAGE])) { 51 | throw new \Exception('wrong msgType'); 52 | } 53 | 54 | $params = [ 55 | 'touser' => $this->toUser, 56 | 'msgtype' => $this->msgType, 57 | ]; 58 | switch ($this->msgType) { 59 | case self::SEND_CUSTOMER_MESSAGE_MSG_TYPE_TEXT: 60 | $params['text'] = $this->text; 61 | break; 62 | case self::SEND_CUSTOMER_MESSAGE_MSG_TYPE_IMAGE: 63 | $params['image'] = $this->image; 64 | break; 65 | } 66 | return $this->post($params,['access_token'=>$this->accessToken]); 67 | } 68 | 69 | } -------------------------------------------------------------------------------- /src/MiniProgram.php: -------------------------------------------------------------------------------- 1 | config = new Config($config); 45 | 46 | } 47 | if ($config instanceof Config) { 48 | $this->config = $config; 49 | } 50 | 51 | if (empty($this->config)) { 52 | throw new \Exception('no config'); 53 | } 54 | $this->initApi(); 55 | return $this; 56 | } 57 | 58 | 59 | protected function initApi() 60 | { 61 | 62 | $class = []; 63 | foreach ($this->apiClass as $api) { 64 | $name = explode('\\', $api); 65 | //$className = strtolower(preg_replace('/(?<=\\w)(?=[A-Z])/', "_$1", array_pop($name))); 66 | $className = lcfirst(array_pop($name)); 67 | $class[$className] = $api; 68 | } 69 | $this->className = $class; 70 | 71 | } 72 | 73 | public function __get($name) 74 | { 75 | if (isset($this->className[$name])) { 76 | if (!isset($this->class[$name])) { 77 | 78 | $new = new $this->className[$name]($this->config); 79 | /* @var $new BaseApi */ 80 | if ($new::NEED_ACCESS_TOKEN == true) { 81 | $new->setAccessToken($this->getToken()); 82 | } 83 | $this->class[$name] = $new; 84 | } 85 | return $this->class[$name]; 86 | } else { 87 | throw new \Exception('api undefined'); 88 | } 89 | } 90 | 91 | protected function getToken() 92 | { 93 | if (empty($this->config->getAccessToken())) { 94 | $token = $this->accessToken->getToken(); 95 | $this->config->setAccessToken($token->accessToken, $token->expiresIn); 96 | } 97 | return $this->config->getAccessToken(); 98 | } 99 | } -------------------------------------------------------------------------------- /src/CurlRequest.php: -------------------------------------------------------------------------------- 1 | 30, 17 | ]; 18 | 19 | protected function __construct() 20 | { 21 | } 22 | 23 | public static function instance($url = null) 24 | { 25 | $instance = new self; 26 | if (null !== $url) { 27 | $instance->setUrl($url); 28 | } 29 | return $instance; 30 | } 31 | 32 | public function setPostField($data) 33 | { 34 | return $this->setOption(CURLOPT_POSTFIELDS, $data); 35 | } 36 | 37 | public function setOption($name, $value) 38 | { 39 | if (in_array($name, array(CURLOPT_RETURNTRANSFER, CURLOPT_HTTPHEADER, CURLOPT_URL))) { 40 | throw new \Exception('cannot set these option'); 41 | } 42 | $this->options[$name] = $value; 43 | return $this; 44 | } 45 | 46 | public function setOptionArray(array $arr) 47 | { 48 | foreach ($arr as $name => $value) { 49 | $this->setOption($name, $value); 50 | } 51 | return $this; 52 | } 53 | 54 | public function setHeader($name, $value) 55 | { 56 | //防注入 57 | $name = str_replace(array("\r", "\n"), '', $name); 58 | $value = str_replace(array("\r", "\n"), '', $value); 59 | 60 | $this->headers[$name] = $value; 61 | return $this; 62 | } 63 | 64 | public function setHeaderArray(array $arr) 65 | { 66 | foreach ($arr as $name => $value) { 67 | $this->setHeader($name, $value); 68 | } 69 | return $this; 70 | } 71 | 72 | public function getOptionArray() 73 | { 74 | $options = $this->options; 75 | $headers = array(); 76 | foreach ($this->headers as $name => $value) { 77 | $headers[] = "$name: $value"; 78 | } 79 | $options[CURLOPT_HTTPHEADER] = $headers; 80 | $options[CURLOPT_RETURNTRANSFER] = true; 81 | $options[CURLOPT_URL] = $this->url; 82 | return $options; 83 | } 84 | 85 | public function setUrl($url) 86 | { 87 | $this->url = $url; 88 | return $this; 89 | } 90 | 91 | public function ignoreSSL() 92 | { 93 | return $this->setOption(CURLOPT_SSL_VERIFYPEER, false) 94 | ->setOption(CURLOPT_SSL_VERIFYHOST, false); 95 | } 96 | 97 | public function setMethod($method) 98 | { 99 | return $this->setOption(CURLOPT_CUSTOMREQUEST, strtoupper($method)); 100 | } 101 | 102 | public function exec()//直接访问 103 | { 104 | $ch = curl_init(); 105 | curl_setopt_array($ch, $this->getOptionArray()); 106 | $result = curl_exec($ch); 107 | $info = curl_getinfo($ch); 108 | return [$result, $info]; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/Api/BaseApi.php: -------------------------------------------------------------------------------- 1 | appId = $config->appId; 41 | $this->secret = $config->secret; 42 | $this->config=$config; 43 | return $this; 44 | } 45 | 46 | public function setAccessToken($token) 47 | { 48 | $this->accessToken = $token; 49 | } 50 | 51 | protected function query($url, $params, $method = 'get') 52 | { 53 | $curl = false; 54 | switch ($method) { 55 | case 'get': 56 | $curl = CurlRequest::instance($url . '?' . http_build_query($params)) 57 | ->exec(); 58 | break; 59 | case 'post': 60 | 61 | $curl = CurlRequest::instance($url) 62 | ->setOption(CURLOPT_POST, 1) 63 | ->setHeader('Content-Type', 'application/json; charset=utf-8') 64 | ->setPostField( 65 | json_encode($params) 66 | )->setHeader('Content-Length', strlen(json_encode($params))) 67 | ->exec(); 68 | break; 69 | 70 | } 71 | if (!$curl[0]) { 72 | throw new Exception('none'); 73 | } 74 | if (static::CURL_RAW == true) { 75 | return $curl[0]; 76 | } 77 | try { 78 | $obj = json_decode($curl[0]); 79 | return $obj; 80 | } catch (\Exception $e) { 81 | throw $e; 82 | } 83 | } 84 | 85 | /** 86 | * @param $params 87 | * @return static 88 | */ 89 | protected function get($params) 90 | { 91 | $url = static::API . '?' . http_build_query($params); 92 | $curl = CurlRequest::instance($url) 93 | ->exec(); 94 | return $this->buildResponse($curl); 95 | } 96 | 97 | /** 98 | * @param $params 99 | * @param array $urlParams 100 | * @return static 101 | */ 102 | protected function post($params, $urlParams = []) 103 | { 104 | if (!empty($urlParams)) { 105 | $url = static::API . '?' . http_build_query($urlParams); 106 | } else { 107 | $url = static::API; 108 | } 109 | $curl = CurlRequest::instance($url) 110 | ->setOption(CURLOPT_POST, 1) 111 | ->setHeader('Content-Type', 'application/json; charset=utf-8') 112 | ->setPostField( 113 | json_encode($params) 114 | )->setHeader('Content-Length', strlen(json_encode($params))) 115 | ->exec(); 116 | return $this->buildResponse($curl); 117 | } 118 | 119 | protected function buildResponse($curl) 120 | { 121 | if (static::CURL_RAW == true) { 122 | return $curl[0]; 123 | } 124 | try { 125 | return $this->jsonToSelf($curl[0]); 126 | } catch (\Exception $e) { 127 | throw $e; 128 | } 129 | } 130 | 131 | protected function jsonToSelf($json) 132 | { 133 | $obj = json_decode($json); 134 | $mapping = static::RESULT_MAPPING; 135 | foreach ($obj as $k => $v) { 136 | if (isset($mapping[$k])) { 137 | $name = $mapping[$k]; 138 | } else { 139 | $name = $this->toCamel($k); 140 | } 141 | $this->$name = $v; 142 | } 143 | return $this; 144 | } 145 | 146 | protected function toCamel($string) 147 | { 148 | return preg_replace_callback( 149 | "/(_([a-z]))/", 150 | function ($match) { 151 | return strtoupper($match[2]); 152 | }, 153 | $string 154 | ); 155 | } 156 | 157 | 158 | } --------------------------------------------------------------------------------