Completed
Push — master ( 73e913...c792b8 )
by Kanto
27s queued 11s
created

HttpClient::get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 4
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Kore : Simple And Minimal Framework
4
 *
5
 */
6
7
namespace Kore;
8
9
use Kore\Log;
10
11
/**
12
 * HttpClient class
13
 *
14
 */
15
class HttpClient
16
{
17
    /**
18
     * connect timeout
19
     *
20
     * Used as the value of CURLOPT_CONNECTTIMEOUT.
21
     * If unspecified, the default is 300.
22
     * For unlimited, specify 0.
23
     * @var int
24
     */
25
    protected $connectTimeout = 300;
26
    /**
27
     * timeout
28
     *
29
     * Used as the value of CURLOPT_TIMEOUT.
30
     * If unspecified, the default is 300.
31
     * For unlimited, specify 0.
32
     * @var int
33
     */
34
    protected $timeout = 300;
35
36
    /**
37
     * Set connect timeout
38
     *
39
     * @param int $connectTimeout connect timeout
40
     * @return void
41
     */
42
    public function setConnectTimeout($connectTimeout)
43
    {
44
        $this->connectTimeout = $connectTimeout;
45
    }
46
47
    /**
48
     * Set timeout
49
     *
50
     * @param int $timeout timeout
51
     * @return void
52
     */
53
    public function setTimeout($timeout)
54
    {
55
        $this->timeout = $timeout;
56
    }
57
    
58
    /**
59
     * GET Communication
60
     *
61
     * @param string $url request url
62
     * @param array<mixed> $params request parameters
63
     * @param array<mixed> $headers request headers
64
     * @param string|null $userpwd user name and password
65
     * @return HttpResponse|false \Kore\HttpResponse
66
     * @see \Kore\HttpResponse
67
     */
68
    public function get($url, $params = [], $headers = [], $userpwd = null)
69
    {
70
        return $this->communicate('GET', $url, $params, $headers, $userpwd);
71
    }
72
73
    /**
74
     * POST Communication
75
     *
76
     * @param string $url request url
77
     * @param array<mixed> $params request parameters
78
     * @param array<mixed> $headers request headers
79
     * @param string|null $userpwd user name and password
80
     * @return HttpResponse|false \Kore\HttpResponse
81
     * @see \Kore\HttpResponse
82
     */
83
    public function post($url, $params = [], $headers = [], $userpwd = null)
84
    {
85
        return $this->communicate('POST', $url, $params, $headers, $userpwd);
86
    }
87
88
    /**
89
     * PUT Communication
90
     *
91
     * @param string $url request url
92
     * @param array<mixed> $params request parameters
93
     * @param array<mixed> $headers request headers
94
     * @param string|null $userpwd user name and password
95
     * @return HttpResponse|false
96
     * @see \Kore\HttpResponse
97
     */
98
    public function put($url, $params = [], $headers = [], $userpwd = null)
99
    {
100
        return $this->communicate('PUT', $url, $params, $headers, $userpwd);
101
    }
102
103
    /**
104
     * PATCH Communication
105
     *
106
     * @param string $url request url
107
     * @param array<mixed> $params request parameters
108
     * @param array<mixed> $headers request headers
109
     * @param string|null $userpwd user name and password
110
     * @return HttpResponse|false \Kore\HttpResponse
111
     * @see \Kore\HttpResponse
112
     */
113
    public function patch($url, $params = [], $headers = [], $userpwd = null)
114
    {
115
        return $this->communicate('PATCH', $url, $params, $headers, $userpwd);
116
    }
117
118
    /**
119
     * DELETE Communication
120
     *
121
     * @param string $url request url
122
     * @param array<mixed> $params request parameters
123
     * @param array<mixed> $headers request headers
124
     * @param string|null $userpwd user name and password
125
     * @return HttpResponse|false \Kore\HttpResponse
126
     * @see \Kore\HttpResponse
127
     */
128
    public function delete($url, $params = [], $headers = [], $userpwd = null)
129
    {
130
        return $this->communicate('DELETE', $url, $params, $headers, $userpwd);
131
    }
132
133
    /**
134
     * Communication Processing
135
     *
136
     * @param string $method http method
137
     * @param string $url request url
138
     * @param array<mixed> $params request parameters
139
     * @param array<mixed> $headers request headers
140
     * @param string|null $userpwd user name and password
141
     * @return HttpResponse|false \Kore\HttpResponse
142
     * @see \Kore\HttpResponse
143
     */
144
    protected function communicate($method, $url, $params = [], $headers = [], $userpwd = null)
145
    {
146
        $headers = $this->buildHeader($headers);
147
        
148
        $curl = curl_init();
149
150
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
151
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
152
        curl_setopt($curl, CURLOPT_HEADER, true);
153
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
154
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
155
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $this->connectTimeout);
156
        curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout);
157
        if ($method === 'GET') {
158
            curl_setopt($curl, CURLOPT_URL, $url . (strpos($url, '?') === false ? '?' : '&') . http_build_query($params));
159
        } elseif ($method === 'POST' || $method === 'PUT' || $method === 'PATCH' || $method === 'DELETE') {
160
            curl_setopt($curl, CURLOPT_URL, $url);
161
            $json_headers = preg_grep("/^Content-Type: application\/json/i", $headers);
162
            if ($json_headers !== false && count($json_headers) > 0) {
163
                $data = json_encode($params);
164
            } else {
165
                $data = http_build_query($params);
166
            }
167
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
168
        }
169
        if (!empty($headers)) {
170
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
171
        }
172
        if ($userpwd !== null) {
173
            curl_setopt($curl, CURLOPT_USERPWD, $userpwd);
174
        }
175
176
        $response = curl_exec($curl);
177
        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
178
        $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
179
        $total_time = curl_getinfo($curl, CURLINFO_TOTAL_TIME);
180
181
        curl_close($curl);
182
183
        Log::debug(sprintf('[%s][%s][%ssec]', $url, $http_code, $total_time));
184
        if ($response === false || !is_string($response)) {
185
            Log::error("Acquisition failed[$http_code]", $response);
186
            return false;
187
        }
188
        $header = substr($response, 0, $header_size);
189
        $body = substr($response, $header_size);
190
        return new HttpResponse($http_code, $header, $body);
191
    }
192
193
    /**
194
     * Build headers
195
     *
196
     * Build the associative array headers into a curl-friendly format.
197
     * @param array<mixed> $headers headers
198
     * @return array<string> built headers
199
     */
200
    protected function buildHeader($headers)
201
    {
202
        $h = array();
203
        foreach ($headers as $key => $value) {
204
            if (is_string($key)) {
205
                $h[] = "$key: $value";
206
            } else {
207
                $h[] = $value;
208
            }
209
        }
210
        return $h;
211
    }
212
}
213
214
/**
215
 * HttpResponse class
216
 *
217
 */
218
class HttpResponse
219
{
220
    /**
221
     * __construct method
222
     *
223
     * @param int $httpCode http status code
224
     * @param string $header response headers
225
     * @param string $body response body
226
     * @return void
227
     */
228
    public function __construct($httpCode, $header, $body)
229
    {
230
        $this->httpCode = $httpCode;
231
        $this->header = $header;
232
        $this->body = $body;
233
    }
234
235
    /**
236
     * http status code
237
     *
238
     * @var int
239
     */
240
    private $httpCode;
241
    /**
242
     * response headers
243
     *
244
     * @var string
245
     */
246
    private $header;
247
    /**
248
     * response body
249
     *
250
     * @var string
251
     */
252
    private $body;
253
254
    /**
255
     * Get the http status code
256
     *
257
     * @return int http status code
258
     */
259
    public function getHttpCode()
260
    {
261
        return $this->httpCode;
262
    }
263
264
    /**
265
     * Get the response headers
266
     *
267
     * @return string response headers
268
     */
269
    public function getHeader()
270
    {
271
        return $this->header;
272
    }
273
274
    /**
275
     * Get the header value by specifying the header name
276
     *
277
     * @param string $key header name
278
     * @return string|null header value
279
     */
280
    public function getHeaderLine($key)
281
    {
282
        preg_match("/$key: (\S*)/i", $this->getHeader(), $matches);
283
        if (!isset($matches[1])) {
284
            return null;
285
        }
286
        return $matches[1];
287
    }
288
289
    /**
290
     * Get the response body
291
     *
292
     * @return string response body
293
     */
294
    public function getBody()
295
    {
296
        return $this->body;
297
    }
298
    
299
    /**
300
     * Get the response body in json format
301
     *
302
     * @return array<mixed> response body
303
     */
304
    public function getJsonBody()
305
    {
306
        return json_decode($this->getBody(), true);
307
    }
308
}
309