Issues (54)

src/Service/Common/Base.php (3 issues)

1
<?php
2
3
namespace tinymeng\Chinaums\Service\Common;
4
5
use Exception;
6
use tinymeng\Chinaums\Exception\TException;
7
use tinymeng\Chinaums\Tools\Http;
8
use tinymeng\tools\FileTool;
9
10
/**
11
 * Base
12
 * @method static \tinymeng\Chinaums\Service\Common\Base request(array $params) 创建请求
13
 */
14
class Base
15
{
16
    /**
17
     * @var array $config 网关
18
     */
19
    protected $config = [];
20
21
    protected $gateway;
22
    protected $gateway_type = 'default';
23
24
    /**
25
     * @var string 接口地址
26
     */
27
    protected $api;
28
    /**
29
     * @var array $body 请求参数
30
     */
31
    protected $body;
32
    /**
33
     * 代码传输过来的请求参数
34
     * @var
35
     */
36
    protected $params;
37
    /**
38
     * 必传的值
39
     * @var array
40
     */
41
    protected $require = [];
42
43
    /**
44
     * @param $config
45
     * @param $params
46
     */
47
    public function __construct($config=[],$params=[])
48
    {
49
        if(!empty($config)){
50
            $this->config = $config;
51
            $this->loadConfigGateway();
52
        }
53
        $this->params = $params;
54
    }
55
56
    /**
57
     * 加载多网关
58
     * @return Base
59
     */
60
    private function loadConfigGateway()
61
    {
62
        $gateway = $this->config['gateway'];// 正式环境
63
        if($this->config['sandbox'] === false){
64
            $this->gateway = isset($gateway[$this->gateway_type]) ? $gateway[$this->gateway_type] : $gateway['default'];// 沙箱环境
65
        }else{
66
            $this->gateway = $gateway['sandbox'];// 沙箱环境
67
        }
68
69
        return $this;
70
    }
71
72
    /**
73
     * @return false|string
74
     * @throws Exception
75
     */
76
    private function loadData()
77
    {
78
        $data = $this->params;
79
        $data['mid'] = $this->config['mid'];
80
        $data['tid'] = $this->config['tid'];
81
        if ($data) {
82
            $this->body = array_merge($this->body, $data);
83
        }
84
        $this->validate();
85
        $data = $this->body;
86
        $data = json_encode($data);
87
        return $data;
88
    }
89
90
    /**
91
     * @return false|mixed|string
92
     */
93
    public function request($params = [])
94
    {
95
        if(!empty($params)){
96
            $this->params = $params;
97
        }
98
99
        try {
100
            $data = $this->loadData();
101
            $sign = $this->generateSign($data);
102
            $gateway  = $this->gateway . $this->api;
103
104
            if ('cli' == php_sapi_name()) {
105
                echo 'api:' . $gateway . PHP_EOL;
106
                echo 'request:' . $data . PHP_EOL;
107
            }
108
            $headers = [
109
                'Content-Type: application/json',
110
                'Content-Length: ' . strlen($data),
111
                'Authorization: ' . $sign
112
            ];
113
            $options = [
114
                CURLOPT_HTTPHEADER => $headers,
115
                CURLOPT_TIMEOUT => 60,
116
                CURLOPT_CONNECTTIMEOUT => 30
117
            ];
118
            $response = Http::post($gateway, $data, $options);
0 ignored issues
show
$data of type string is incompatible with the type array expected by parameter $params of tinymeng\Chinaums\Tools\Http::post(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

118
            $response = Http::post($gateway, /** @scrutinizer ignore-type */ $data, $options);
Loading history...
119
            $this->writeLog('Request url:'.$gateway.PHP_EOL.'params:'.json_encode($data).PHP_EOL.'options:'.json_encode($options).PHP_EOL.'response'.$response);
120
            return $response;
121
        } catch (Exception $e) {
122
            if ('cli' == php_sapi_name()) {
123
                echo $e->getMessage() . PHP_EOL;
124
            }
125
            throw new TException("Chinaums request error:".$e->getMessage());
126
        }
127
    }
128
129
    /**
130
     * @return string
131
     */
132
    public function formRequest()
133
    {
134
        try {
135
            $data = $this->loadData();
136
            $params = $this->generateSign($data,true);
137
            $gateway  = $this->gateway . $this->api;
138
139
            $data = json_encode($data);
140
            if ('cli' == php_sapi_name()) {
141
                echo 'api:' . $gateway . PHP_EOL;
142
                echo 'request:' . $data . PHP_EOL;
143
            }
144
145
            $options = [
146
                CURLOPT_TIMEOUT => 60,
147
                CURLOPT_CONNECTTIMEOUT => 30
148
            ];
149
            $response = Http::get($gateway,$params,$options);
0 ignored issues
show
$params of type string is incompatible with the type array expected by parameter $params of tinymeng\Chinaums\Tools\Http::get(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

149
            $response = Http::get($gateway,/** @scrutinizer ignore-type */ $params,$options);
Loading history...
150
            $this->writeLog('formRequest url:'.$gateway.PHP_EOL.'params:'.json_encode($data).PHP_EOL.'options:'.json_encode($options).PHP_EOL.'response'.$response);
151
            return $response;
152
        } catch (Exception $e) {
153
            throw new TException("Chinaums formRequest error:".$e->getMessage());
154
        }
155
    }
156
157
    /**
158
     * @param $config
159
     * @return $this
160
     */
161
    public function setConfig($config)
162
    {
163
        $this->config = $config;
164
        $this->loadConfigGateway();
165
        return $this;
166
    }
167
168
    /**
169
     * @param $value
170
     * @return $this
171
     */
172
    public function setBody($value)
173
    {
174
        $this->body = array_merge($this->body, $value);
175
        return $this;
176
    }
177
178
    /**
179
     * @return true
180
     * @throws Exception
181
     */
182
    protected function validate()
183
    {
184
        $require = $this->require;
185
        $key = array_keys($this->body);
186
187
        foreach ($require as $v) {
188
            if (!in_array($v, $key)) {
189
                throw new Exception($v . ' is require!!');
190
            }
191
        }
192
        return true;
193
    }
194
    /**
195
     * 根绝类型生成sign
196
     * @param $params
197
     * @param string $signType
198
     * @return string
199
     */
200
    public function generateSign($body,$openForm=false)
201
    {
202
        $body = (!is_string($body)) ? json_encode($body) : $body;
203
        $appid = $this->config['appid'];
204
        $appkey = $this->config['appkey'];
205
        $timestamp = date("YmdHis", time());
206
        $nonce = md5(uniqid(microtime(true), true));
207
        $str = bin2hex(hash('sha256', $body, true));
208
        $signature = base64_encode(hash_hmac('sha256', "$appid$timestamp$nonce$str", $appkey, true));
209
        $authorization = "OPEN-BODY-SIG AppId=\"$appid\", Timestamp=\"$timestamp\", Nonce=\"$nonce\", Signature=\"$signature\"";
210
        if($openForm){
211
            $params = [
212
                'appId'=>$appid,
213
                'timestamp'=>$timestamp,
214
                'nonce'=>$nonce,
215
                'content'=>$body,
216
                'signature'=>$signature,
217
                'authorization'=>'OPEN-FORM-PARAM',
218
            ];
219
            return $params;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $params returns the type array<string,mixed|string> which is incompatible with the documented return type string.
Loading history...
220
        }
221
        return $authorization;
222
    }
223
224
    /**
225
     * @param $name
226
     * @param $value
227
     * @return void
228
     */
229
    public function __set($name, $value)
230
    {
231
        $this->body[$name] = $value;
232
    }
233
234
    /**
235
     * @param $message
236
     * @param $file_name
237
     * @return void
238
     */
239
    private function writeLog($message,$file_name = 'chinaums')
240
    {
241
        FileTool::writeLog($message,$file_name);
242
    }
243
}
244