Showing
1 changed file
with
476 additions
and
471 deletions
1 | -<?php | ||
2 | - | ||
3 | -/** | ||
4 | - * 有货相关接口类 | ||
5 | - * | ||
6 | - * @name Yohobuy | ||
7 | - * @package library/Api | ||
8 | - * @copyright yoho.inc | ||
9 | - * @version 1.0 (2015-9-30 16:42:51) | ||
10 | - * @author fei.hong <fei.hong@yoho.cn> | ||
11 | - */ | ||
12 | - | ||
13 | -namespace Api; | ||
14 | - | ||
15 | -use Plugin\Cache; | ||
16 | - | ||
17 | -class Yohobuy | ||
18 | -{ | ||
19 | - /* 正式环境 */ | ||
20 | - | ||
21 | -// const API_URL = 'http://api2.open.yohobuy.com/'; | ||
22 | -// const API_URL2 = 'http://api.open.yohobuy.com/'; | ||
23 | -// const SERVICE_URL = 'http://service.api.yohobuy.com/'; | ||
24 | -// const YOHOBUY_URL = 'http://www.yohobuy.com/'; | ||
25 | - | ||
26 | -// const API_URL = 'http://apih5.yoho.cn/'; | ||
27 | -// const API_URL2 = 'http://apih5.yoho.cn/'; | ||
28 | -// const SERVICE_URL = 'http://serviceh5.yoho.cn/'; | ||
29 | -// const YOHOBUY_URL = 'http://www.yohobuy.com/'; | ||
30 | -// const API_OLD = 'http://api2.open.yohobuy.com/'; | ||
31 | - | ||
32 | -// /* 测试环境 */ | ||
33 | -// const API_URL = 'http://testapi.yoho.cn:28078/'; | ||
34 | -// const SERVICE_URL = 'http://testservice.yoho.cn:28077/'; | ||
35 | -// const YOHOBUY_URL = 'http://www.yohobuy.com/'; | ||
36 | -// const API_OLD = 'http://test2.open.yohobuy.com/'; | ||
37 | - | ||
38 | - /* 预览环境 */ | ||
39 | - const API_URL = 'http://preapi.yoho.cn/'; | ||
40 | - const API_URL2 = 'http://preapi.yoho.cn/'; | ||
41 | - const SERVICE_URL = 'http://serviceh5.yoho.cn/'; | ||
42 | - const YOHOBUY_URL = 'http://www.yohobuy.com/'; | ||
43 | - const API_OLD = 'http://api2.open.yohobuy.com/'; | ||
44 | - | ||
45 | - /** | ||
46 | - * 私钥列表 | ||
47 | - * | ||
48 | - * @var array | ||
49 | - */ | ||
50 | - public static $privateKeyList = array( | ||
51 | - 'android' => 'fd4ad5fcfa0de589ef238c0e7331b585', | ||
52 | - 'iphone' => 'a85bb0674e08986c6b115d5e3a4884fa', | ||
53 | - 'ipad' => 'ad9fcda2e679cf9229e37feae2cdcf80', | ||
54 | - 'web' => '0ed29744ed318fd28d2c07985d3ba633', | ||
55 | - ); | ||
56 | - | ||
57 | - /** | ||
58 | - * 取得当前的客户端类型 | ||
59 | - */ | ||
60 | - public static function clientType() | ||
61 | - { | ||
62 | - // 苹果设备 | ||
63 | - if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone')) { | ||
64 | - return 'iphone'; | ||
65 | - } | ||
66 | - // 苹果IPAD | ||
67 | - elseif (strstr($_SERVER['HTTP_USER_AGENT'], 'iPad')) { | ||
68 | - return 'ipad'; | ||
69 | - } | ||
70 | - elseif (stristr($_SERVER['HTTP_USER_AGENT'], 'android')) { | ||
71 | - return 'android'; | ||
72 | - } | ||
73 | - // 其它 | ||
74 | - else { | ||
75 | - return 'web'; | ||
76 | - } | ||
77 | - } | ||
78 | - | ||
79 | - /** | ||
80 | - * 取得当前的IP地址 | ||
81 | - * | ||
82 | - * @param bool $int 返回int类型的ip地址,默认是 | ||
83 | - * @return mixed 当前的IP地址 | ||
84 | - */ | ||
85 | - public static function ip($int = true) | ||
86 | - { | ||
87 | - if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP']) { | ||
88 | - $onlineip = $_SERVER['HTTP_CLIENT_IP']; | ||
89 | - } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']) { | ||
90 | - $onlineip = $_SERVER['HTTP_X_FORWARDED_FOR']; | ||
91 | - } else { | ||
92 | - $onlineip = $_SERVER['REMOTE_ADDR']; | ||
93 | - } | ||
94 | - | ||
95 | - return $int ? ip2long($onlineip) : $onlineip; | ||
96 | - } | ||
97 | - | ||
98 | - /** | ||
99 | - * 取得公共的参数 | ||
100 | - * | ||
101 | - * @return array | ||
102 | - */ | ||
103 | - public static function param() | ||
104 | - { | ||
105 | - $clientType = self::clientType(); | ||
106 | - $param = array( | ||
107 | - 'app_version' => '3.8.2', | ||
108 | - 'client_type' => $clientType, | ||
109 | - 'os_version' => 'yohobuy:h5', | ||
110 | - 'private_key' => self::$privateKeyList[$clientType], | ||
111 | - 'screen_size' => '720x1280', | ||
112 | - 'v' => '7', | ||
113 | - ); | ||
114 | - return $param; | ||
115 | - } | ||
116 | - | ||
117 | - /** | ||
118 | - * 构建URL | ||
119 | - * | ||
120 | - * @param string $url | ||
121 | - * @param array $data | ||
122 | - * @return string | ||
123 | - */ | ||
124 | - public static function httpBuildQuery($url, $data) | ||
125 | - { | ||
126 | - // 销毁私钥参数 | ||
127 | - if (isset($data['private_key'])) { | ||
128 | - unset($data['private_key']); | ||
129 | - } | ||
130 | - if (strstr($url, '?') !== false) { | ||
131 | - $url .= '&' . http_build_query($data, null, '&'); | ||
132 | - } else { | ||
133 | - $url .= '?' . http_build_query($data, null, '&'); | ||
134 | - } | ||
135 | - return $url; | ||
136 | - } | ||
137 | - | ||
138 | - /** | ||
139 | - * get方式调用接口 | ||
140 | - * | ||
141 | - * @param string $url 接口URL | ||
142 | - * @param array $data 参数列表 | ||
143 | - * @parma mixed $cache 控制是否启用接口数据的缓存(时间单位为秒). 如3600表示缓存1小时, false表示不缓存 | ||
144 | - * @param bool $returnJson 控制是否返回json格式数据 | ||
145 | - * @param int $timeout 超时时间 | ||
146 | - * @return mixed | ||
147 | - */ | ||
148 | - public static function get($url, $data = array(), $cache = false, $returnJson = false, $timeout = 5) | ||
149 | - { | ||
150 | - // 销毁私钥参数 | ||
151 | - if (isset($data['private_key'])) { | ||
152 | - unset($data['private_key']); | ||
153 | - } | ||
154 | - if (!empty($data)) { | ||
155 | - $url = self::httpBuildQuery($url, $data); | ||
156 | - } | ||
157 | - | ||
158 | - /* 开启缓存的情况 */ | ||
159 | - if ($cache && USE_CACHE) { | ||
160 | - // 先尝试获取一级缓存(master), 有数据则直接返回. | ||
161 | - $result = Cache::get($url, 'master'); | ||
162 | - if (!empty($result)) { | ||
163 | - return $result; | ||
164 | - } | ||
165 | - } | ||
166 | - | ||
167 | - $ch = curl_init($url); | ||
168 | - curl_setopt($ch, CURLOPT_HEADER, 0); | ||
169 | - curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | ||
170 | - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
171 | - $result = curl_exec($ch); | ||
172 | - if (!$returnJson && !empty($result)) { | ||
173 | - $result = json_decode($result, true); | ||
174 | - } | ||
175 | - | ||
176 | - curl_close($ch); | ||
177 | - $data = array(); | ||
178 | - | ||
179 | - /* 开启缓存的情况 */ | ||
180 | - if ($cache && USE_CACHE) { | ||
181 | - // 接口调用异常时, 不害怕,从我们的二级缓存(slave)里再取数据. | ||
182 | - if (empty($result)) { | ||
183 | - $result = Cache::get($url, 'slave'); | ||
184 | - } | ||
185 | - // 接口调用成功时,这里会设置一级(master)和二级(slave)的缓存数据. | ||
186 | - else { | ||
187 | - Cache::set($url, $result, $cache); | ||
188 | - } | ||
189 | - } | ||
190 | - | ||
191 | - return $result; | ||
192 | - } | ||
193 | - | ||
194 | - /** | ||
195 | - * post提交数据 | ||
196 | - * | ||
197 | - * @param string $url 接口URL | ||
198 | - * @param array $data 参数列表 | ||
199 | - * @param bool $returnJson 控制是否返回json格式数据 | ||
200 | - * @param int $timeout 超时时间 | ||
201 | - * @param array $header | ||
202 | - * @param array $cookie | ||
203 | - * @return mixed | ||
204 | - */ | ||
205 | - public static function post($url, $data = array(), $returnJson = false, $timeout = 10, $header = array(), $cookie = array()) | ||
206 | - { | ||
207 | - $ch = curl_init($url); | ||
208 | - | ||
209 | - curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | ||
210 | - if (!empty($header)) { | ||
211 | - curl_setopt($ch, CURLOPT_HTTPHEADER, $header); | ||
212 | - } else { | ||
213 | - curl_setopt($ch, CURLOPT_HEADER, 0); | ||
214 | - } | ||
215 | - | ||
216 | - if (!empty($cookie)) { | ||
217 | - $cookie_str = array(); | ||
218 | - foreach ($cookie as $key => $val) { | ||
219 | - $cookie_str[] = urlencode($key) . '=' . urlencode($val); | ||
220 | - } | ||
221 | - curl_setopt($ch, CURLOPT_COOKIE, implode(';', $cookie_str)); | ||
222 | - } | ||
223 | - | ||
224 | - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
225 | - curl_setopt($ch, CURLOPT_POST, true); | ||
226 | - // 销毁私钥参数 | ||
227 | - if (isset($data['private_key'])) { | ||
228 | - unset($data['private_key']); | ||
229 | - } | ||
230 | - if (!empty($data)) { | ||
231 | - $str = http_build_query($data, null, '&'); | ||
232 | - // 新加支持application/x-www-form-urlencoded调用方式 | ||
233 | - //curl_setopt($ch, CURLOPT_POSTFIELDS, $data); | ||
234 | - curl_setopt($ch, CURLOPT_POSTFIELDS, $str); | ||
235 | - } | ||
236 | - $result = curl_exec($ch); | ||
237 | - if (!$returnJson && !empty($result)) { | ||
238 | - $result = json_decode($result, true); | ||
239 | - } | ||
240 | - curl_close($ch); | ||
241 | - $data = array(); | ||
242 | - | ||
243 | - return $result; | ||
244 | - } | ||
245 | - | ||
246 | - /** | ||
247 | - * 批量调用接口 | ||
248 | - * | ||
249 | - * @param array $urlList 接口列表 | ||
250 | - * @param array $options CURL设置项 | ||
251 | - * @parma mixed $cache 控制是否启用接口数据的缓存(时间单位为秒). 如3600表示缓存1小时, false表示不缓存 | ||
252 | - * @param int $timeout 超时时间,单位是秒 | ||
253 | - * @return array | ||
254 | - */ | ||
255 | - public static function getMulti($urlList = array(), $options = array(), $cache = false, $timeout = 5) | ||
256 | - { | ||
257 | - /* 开启缓存的情况 */ | ||
258 | - if ($cache && USE_CACHE) { | ||
259 | - $key = md5(implode(',', array_values($urlList))); | ||
260 | - // 先尝试获取一级缓存(master), 有数据则直接返回. | ||
261 | - $result = Cache::get($key, 'master'); | ||
262 | - if (!empty($result)) { | ||
263 | - return $result; | ||
264 | - } | ||
265 | - } | ||
266 | - | ||
267 | - $result = array(); | ||
268 | - $response = array(); | ||
269 | - $running = 0; | ||
270 | - $data = ''; | ||
271 | - $error = ''; | ||
272 | - $defaultOptions = array( | ||
273 | - CURLOPT_HEADER => 0, | ||
274 | - CURLOPT_RETURNTRANSFER => 1, | ||
275 | - CURLOPT_CONNECTTIMEOUT => $timeout, | ||
276 | - CURLOPT_TIMEOUT => $timeout, | ||
277 | - CURLOPT_NOSIGNAL => 1, //忽略所有的curl传递给php的信号,减少并发crash | ||
278 | - ); | ||
279 | - $mh = curl_multi_init(); | ||
280 | - $ch = array(); | ||
281 | - | ||
282 | - // 应用CURL配置 | ||
283 | - if (empty($options)) { | ||
284 | - $options = $defaultOptions; | ||
285 | - } else { | ||
286 | - $options = array_merge($defaultOptions, $options); | ||
287 | - } | ||
288 | - | ||
289 | - // 添加子链接句柄 | ||
290 | - foreach ($urlList as $name => $api) { | ||
291 | - $ch[$name] = curl_init($api); | ||
292 | - curl_setopt_array($ch[$name], $options); | ||
293 | - curl_multi_add_handle($mh, $ch[$name]); | ||
294 | - $result[$name] = array(); | ||
295 | - } | ||
296 | - | ||
297 | - // 调用API接口 | ||
298 | - do { | ||
299 | - do { | ||
300 | - $status = curl_multi_exec($mh, $running); | ||
301 | - } while ($status == CURLM_CALL_MULTI_PERFORM); | ||
302 | - | ||
303 | - if ($status != CURLM_OK) { | ||
304 | - break; | ||
305 | - } | ||
306 | - | ||
307 | - if ($running > 0) { | ||
308 | - curl_multi_select($mh, 0.5); | ||
309 | - } | ||
310 | - } while ($running); | ||
311 | - | ||
312 | - // 获取API接口响应的结果 | ||
313 | - foreach ($urlList as $name => $api) { | ||
314 | - $error = curl_error($ch[$name]); | ||
315 | - if ($error != '') { | ||
316 | - continue; | ||
317 | - } | ||
318 | - | ||
319 | - $data = curl_multi_getcontent($ch[$name]); | ||
320 | - if (!$data) { | ||
321 | - continue; | ||
322 | - } | ||
323 | - | ||
324 | - $response = json_decode($data, true); | ||
325 | - if (empty($response['data'])) { | ||
326 | - continue; | ||
327 | - } | ||
328 | - $result[$name] = $response['data']; | ||
329 | - | ||
330 | - curl_multi_remove_handle($mh, $ch[$name]); | ||
331 | - curl_close($ch[$name]); | ||
332 | - } | ||
333 | - curl_multi_close($mh); | ||
334 | - | ||
335 | - /* 开启缓存的情况 */ | ||
336 | - if ($cache && USE_CACHE) { | ||
337 | - // 接口调用异常时, 不害怕,从我们的二级缓存(slave)里再取数据. | ||
338 | - if (empty($result[$name])) { | ||
339 | - $result = Cache::get($key, 'slave'); | ||
340 | - } | ||
341 | - // 接口调用成功时,这里会设置一级(master)和二级(slave)的缓存数据. | ||
342 | - else { | ||
343 | - Cache::set($key, $result, $cache); | ||
344 | - } | ||
345 | - } | ||
346 | - | ||
347 | - return $result; | ||
348 | - } | ||
349 | - | ||
350 | - /** | ||
351 | - * rpc调用远程服务(YAR) | ||
352 | - * | ||
353 | - * @see http://php.net/manual/zh/yar-client.setopt.php | ||
354 | - * @param string $uri | ||
355 | - * @param string $method | ||
356 | - * @param array $parameters | ||
357 | - * @param mixed $cache 控制是否启用接口数据的缓存(时间单位为秒). 如3600表示缓存1小时, false表示不缓存 | ||
358 | - * @param int $timeout | ||
359 | - * @return array | ||
360 | - */ | ||
361 | - public static function yarClient($uri, $method, $parameters = array(), $cache = false, $timeout = 3000) | ||
362 | - { | ||
363 | - /* 开启缓存的情况 */ | ||
364 | - if ($cache && USE_CACHE) { | ||
365 | - $key = self::httpBuildQuery($uri . $method, $parameters); | ||
366 | - // 先尝试获取一级缓存(master), 有数据则直接返回. | ||
367 | - $result = Cache::get($key, 'master'); | ||
368 | - if (!empty($result)) { | ||
369 | - return $result; | ||
370 | - } | ||
371 | - } | ||
372 | - | ||
373 | - $client = new \Yar_Client($uri); | ||
374 | - $client->SetOpt(YAR_OPT_PACKAGER, 'php'); | ||
375 | - $client->SetOpt(YAR_OPT_TIMEOUT, $timeout); | ||
376 | - $client->SetOpt(YAR_OPT_CONNECT_TIMEOUT, $timeout); | ||
377 | - | ||
378 | - try { | ||
379 | - $result = call_user_func_array(array($client, $method), $parameters); | ||
380 | - } catch (\Exception $e) { | ||
381 | - $result = array(); | ||
382 | - } | ||
383 | - | ||
384 | - /* 开启缓存的情况 */ | ||
385 | - if ($cache && USE_CACHE) { | ||
386 | - // 接口调用异常时, 不害怕,从我们的二级缓存(slave)里再取数据. | ||
387 | - if (empty($result)) { | ||
388 | - $result = Cache::get($key, 'slave'); | ||
389 | - } | ||
390 | - // 接口调用成功时,这里会设置一级(master)和二级(slave)的缓存数据. | ||
391 | - else { | ||
392 | - Cache::set($key, $result, $cache); | ||
393 | - } | ||
394 | - } | ||
395 | - | ||
396 | - return $result; | ||
397 | - } | ||
398 | - | ||
399 | - /** | ||
400 | - * 并行(异步)调用远程服务 | ||
401 | - * | ||
402 | - * @see http://php.net/manual/zh/class.yar-concurrent-client.php | ||
403 | - * @param string $uri | ||
404 | - * @param string $method | ||
405 | - * @param array $parameter | ||
406 | - * @param callable $callback | ||
407 | - * @param int $timeout | ||
408 | - * @return void | ||
409 | - */ | ||
410 | - public static function yarConcurrentCall($uri, $method, $parameters, $callback, $timeout = 3000) | ||
411 | - { | ||
412 | - \Yar_Concurrent_Client::call($uri, $method, $parameters, $callback, null, array( | ||
413 | - YAR_OPT_PACKAGER => 'php', | ||
414 | - YAR_OPT_TIMEOUT => $timeout, | ||
415 | - YAR_OPT_CONNECT_TIMEOUT => $timeout | ||
416 | - )); | ||
417 | - } | ||
418 | - | ||
419 | - public static function yarConcurrentLoop($callback = null) | ||
420 | - { | ||
421 | - \Yar_Concurrent_Client::loop($callback); | ||
422 | - } | ||
423 | - | ||
424 | - /** | ||
425 | - * 提交json格式数据请求java有关接口 | ||
426 | - * | ||
427 | - * @param string $url 接口URL | ||
428 | - * @param array $data 参数列表 | ||
429 | - * @param bool $returnJson 控制是否返回json格式数据 | ||
430 | - * @param int $timeout 超时时间 | ||
431 | - * @param array $cookie | ||
432 | - * @return mixed | ||
433 | - */ | ||
434 | - public static function jsonPost($url, $data = array(), $returnJson = false, $timeout = 10, $cookie = array()) | ||
435 | - { | ||
436 | - $ch = curl_init($url); | ||
437 | - | ||
438 | - curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | ||
439 | - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); | ||
440 | - | ||
441 | - if (!empty($cookie)) { | ||
442 | - $cookie_str = array(); | ||
443 | - foreach ($cookie as $key => $val) { | ||
444 | - $cookie_str[] = urlencode($key) . '=' . urlencode($val); | ||
445 | - } | ||
446 | - curl_setopt($ch, CURLOPT_COOKIE, implode(';', $cookie_str)); | ||
447 | - } | ||
448 | - | ||
449 | - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
450 | - | ||
451 | - if (!empty($data)) { | ||
452 | - $data_string = json_encode($data); | ||
453 | - | ||
454 | - curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); | ||
455 | - // 设置json的Header | ||
456 | - curl_setopt($ch, CURLOPT_HTTPHEADER, array( | ||
457 | - 'Content-Type: application/json', | ||
458 | - 'Content-Length: ' . strlen($data_string) | ||
459 | - )); | ||
460 | - } | ||
461 | - $result = curl_exec($ch); | ||
462 | - if (!$returnJson && !empty($result)) { | ||
463 | - $result = json_decode($result, true); | ||
464 | - } | ||
465 | - curl_close($ch); | ||
466 | - $data = array(); | ||
467 | - | ||
468 | - return $result; | ||
469 | - } | ||
470 | - | ||
471 | -} | 1 | +<?php |
2 | + | ||
3 | +/** | ||
4 | + * 有货相关接口类 | ||
5 | + * | ||
6 | + * @name Yohobuy | ||
7 | + * @package library/Api | ||
8 | + * @copyright yoho.inc | ||
9 | + * @version 1.0 (2015-9-30 16:42:51) | ||
10 | + * @author fei.hong <fei.hong@yoho.cn> | ||
11 | + */ | ||
12 | + | ||
13 | +namespace Api; | ||
14 | + | ||
15 | +use Plugin\Cache; | ||
16 | + | ||
17 | +class Yohobuy | ||
18 | +{ | ||
19 | + /* 正式环境 */ | ||
20 | + | ||
21 | +// const API_URL = 'http://api2.open.yohobuy.com/'; | ||
22 | +// const API_URL2 = 'http://api.open.yohobuy.com/'; | ||
23 | +// const SERVICE_URL = 'http://service.api.yohobuy.com/'; | ||
24 | +// const YOHOBUY_URL = 'http://www.yohobuy.com/'; | ||
25 | + | ||
26 | +// const API_URL = 'http://apih5.yoho.cn/'; | ||
27 | +// const API_URL2 = 'http://apih5.yoho.cn/'; | ||
28 | +// const SERVICE_URL = 'http://serviceh5.yoho.cn/'; | ||
29 | +// const YOHOBUY_URL = 'http://www.yohobuy.com/'; | ||
30 | +// const API_OLD = 'http://api2.open.yohobuy.com/'; | ||
31 | + | ||
32 | +// /* 测试环境 */ | ||
33 | +// const API_URL = 'http://testapi.yoho.cn:28078/'; | ||
34 | +// const SERVICE_URL = 'http://testservice.yoho.cn:28077/'; | ||
35 | +// const YOHOBUY_URL = 'http://www.yohobuy.com/'; | ||
36 | +// const API_OLD = 'http://test2.open.yohobuy.com/'; | ||
37 | + | ||
38 | + /* 预览环境 */ | ||
39 | + const API_URL = 'http://preapi.yoho.cn/'; | ||
40 | + const API_URL2 = 'http://preapi.yoho.cn/'; | ||
41 | + const SERVICE_URL = 'http://serviceh5.yoho.cn/'; | ||
42 | + const YOHOBUY_URL = 'http://www.yohobuy.com/'; | ||
43 | + const API_OLD = 'http://api2.open.yohobuy.com/'; | ||
44 | + | ||
45 | + /*PC重构地址*/ | ||
46 | +// const API_URL = 'http://test2.open.yohobuy.com/'; | ||
47 | +// const SERVICE_URL = 'http://test.service.api.yohobuy.com/'; | ||
48 | +// const YOHOBUY_URL = 'http://www.yohobuy.com/'; | ||
49 | + | ||
50 | + /** | ||
51 | + * 私钥列表 | ||
52 | + * | ||
53 | + * @var array | ||
54 | + */ | ||
55 | + public static $privateKeyList = array( | ||
56 | + 'android' => 'fd4ad5fcfa0de589ef238c0e7331b585', | ||
57 | + 'iphone' => 'a85bb0674e08986c6b115d5e3a4884fa', | ||
58 | + 'ipad' => 'ad9fcda2e679cf9229e37feae2cdcf80', | ||
59 | + 'web' => '0ed29744ed318fd28d2c07985d3ba633', | ||
60 | + ); | ||
61 | + | ||
62 | + /** | ||
63 | + * 取得当前的客户端类型 | ||
64 | + */ | ||
65 | + public static function clientType() | ||
66 | + { | ||
67 | + // 苹果设备 | ||
68 | + if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone')) { | ||
69 | + return 'iphone'; | ||
70 | + } | ||
71 | + // 苹果IPAD | ||
72 | + elseif (strstr($_SERVER['HTTP_USER_AGENT'], 'iPad')) { | ||
73 | + return 'ipad'; | ||
74 | + } | ||
75 | + elseif (stristr($_SERVER['HTTP_USER_AGENT'], 'android')) { | ||
76 | + return 'android'; | ||
77 | + } | ||
78 | + // 其它 | ||
79 | + else { | ||
80 | + return 'web'; | ||
81 | + } | ||
82 | + } | ||
83 | + | ||
84 | + /** | ||
85 | + * 取得当前的IP地址 | ||
86 | + * | ||
87 | + * @param bool $int 返回int类型的ip地址,默认是 | ||
88 | + * @return mixed 当前的IP地址 | ||
89 | + */ | ||
90 | + public static function ip($int = true) | ||
91 | + { | ||
92 | + if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP']) { | ||
93 | + $onlineip = $_SERVER['HTTP_CLIENT_IP']; | ||
94 | + } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']) { | ||
95 | + $onlineip = $_SERVER['HTTP_X_FORWARDED_FOR']; | ||
96 | + } else { | ||
97 | + $onlineip = $_SERVER['REMOTE_ADDR']; | ||
98 | + } | ||
99 | + | ||
100 | + return $int ? ip2long($onlineip) : $onlineip; | ||
101 | + } | ||
102 | + | ||
103 | + /** | ||
104 | + * 取得公共的参数 | ||
105 | + * | ||
106 | + * @return array | ||
107 | + */ | ||
108 | + public static function param() | ||
109 | + { | ||
110 | + $clientType = self::clientType(); | ||
111 | + $param = array( | ||
112 | + 'app_version' => '3.8.2', | ||
113 | + 'client_type' => $clientType, | ||
114 | + 'os_version' => 'yohobuy:h5', | ||
115 | + 'private_key' => self::$privateKeyList[$clientType], | ||
116 | + 'screen_size' => '720x1280', | ||
117 | + 'v' => '7', | ||
118 | + ); | ||
119 | + return $param; | ||
120 | + } | ||
121 | + | ||
122 | + /** | ||
123 | + * 构建URL | ||
124 | + * | ||
125 | + * @param string $url | ||
126 | + * @param array $data | ||
127 | + * @return string | ||
128 | + */ | ||
129 | + public static function httpBuildQuery($url, $data) | ||
130 | + { | ||
131 | + // 销毁私钥参数 | ||
132 | + if (isset($data['private_key'])) { | ||
133 | + unset($data['private_key']); | ||
134 | + } | ||
135 | + if (strstr($url, '?') !== false) { | ||
136 | + $url .= '&' . http_build_query($data, null, '&'); | ||
137 | + } else { | ||
138 | + $url .= '?' . http_build_query($data, null, '&'); | ||
139 | + } | ||
140 | + return $url; | ||
141 | + } | ||
142 | + | ||
143 | + /** | ||
144 | + * get方式调用接口 | ||
145 | + * | ||
146 | + * @param string $url 接口URL | ||
147 | + * @param array $data 参数列表 | ||
148 | + * @parma mixed $cache 控制是否启用接口数据的缓存(时间单位为秒). 如3600表示缓存1小时, false表示不缓存 | ||
149 | + * @param bool $returnJson 控制是否返回json格式数据 | ||
150 | + * @param int $timeout 超时时间 | ||
151 | + * @return mixed | ||
152 | + */ | ||
153 | + public static function get($url, $data = array(), $cache = false, $returnJson = false, $timeout = 5) | ||
154 | + { | ||
155 | + // 销毁私钥参数 | ||
156 | + if (isset($data['private_key'])) { | ||
157 | + unset($data['private_key']); | ||
158 | + } | ||
159 | + if (!empty($data)) { | ||
160 | + $url = self::httpBuildQuery($url, $data); | ||
161 | + } | ||
162 | + | ||
163 | + /* 开启缓存的情况 */ | ||
164 | + if ($cache && USE_CACHE) { | ||
165 | + // 先尝试获取一级缓存(master), 有数据则直接返回. | ||
166 | + $result = Cache::get($url, 'master'); | ||
167 | + if (!empty($result)) { | ||
168 | + return $result; | ||
169 | + } | ||
170 | + } | ||
171 | + | ||
172 | + $ch = curl_init($url); | ||
173 | + curl_setopt($ch, CURLOPT_HEADER, 0); | ||
174 | + curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | ||
175 | + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
176 | + $result = curl_exec($ch); | ||
177 | + if (!$returnJson && !empty($result)) { | ||
178 | + $result = json_decode($result, true); | ||
179 | + } | ||
180 | + | ||
181 | + curl_close($ch); | ||
182 | + $data = array(); | ||
183 | + | ||
184 | + /* 开启缓存的情况 */ | ||
185 | + if ($cache && USE_CACHE) { | ||
186 | + // 接口调用异常时, 不害怕,从我们的二级缓存(slave)里再取数据. | ||
187 | + if (empty($result)) { | ||
188 | + $result = Cache::get($url, 'slave'); | ||
189 | + } | ||
190 | + // 接口调用成功时,这里会设置一级(master)和二级(slave)的缓存数据. | ||
191 | + else { | ||
192 | + Cache::set($url, $result, $cache); | ||
193 | + } | ||
194 | + } | ||
195 | + | ||
196 | + return $result; | ||
197 | + } | ||
198 | + | ||
199 | + /** | ||
200 | + * post提交数据 | ||
201 | + * | ||
202 | + * @param string $url 接口URL | ||
203 | + * @param array $data 参数列表 | ||
204 | + * @param bool $returnJson 控制是否返回json格式数据 | ||
205 | + * @param int $timeout 超时时间 | ||
206 | + * @param array $header | ||
207 | + * @param array $cookie | ||
208 | + * @return mixed | ||
209 | + */ | ||
210 | + public static function post($url, $data = array(), $returnJson = false, $timeout = 10, $header = array(), $cookie = array()) | ||
211 | + { | ||
212 | + $ch = curl_init($url); | ||
213 | + | ||
214 | + curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | ||
215 | + if (!empty($header)) { | ||
216 | + curl_setopt($ch, CURLOPT_HTTPHEADER, $header); | ||
217 | + } else { | ||
218 | + curl_setopt($ch, CURLOPT_HEADER, 0); | ||
219 | + } | ||
220 | + | ||
221 | + if (!empty($cookie)) { | ||
222 | + $cookie_str = array(); | ||
223 | + foreach ($cookie as $key => $val) { | ||
224 | + $cookie_str[] = urlencode($key) . '=' . urlencode($val); | ||
225 | + } | ||
226 | + curl_setopt($ch, CURLOPT_COOKIE, implode(';', $cookie_str)); | ||
227 | + } | ||
228 | + | ||
229 | + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
230 | + curl_setopt($ch, CURLOPT_POST, true); | ||
231 | + // 销毁私钥参数 | ||
232 | + if (isset($data['private_key'])) { | ||
233 | + unset($data['private_key']); | ||
234 | + } | ||
235 | + if (!empty($data)) { | ||
236 | + $str = http_build_query($data, null, '&'); | ||
237 | + // 新加支持application/x-www-form-urlencoded调用方式 | ||
238 | + //curl_setopt($ch, CURLOPT_POSTFIELDS, $data); | ||
239 | + curl_setopt($ch, CURLOPT_POSTFIELDS, $str); | ||
240 | + } | ||
241 | + $result = curl_exec($ch); | ||
242 | + if (!$returnJson && !empty($result)) { | ||
243 | + $result = json_decode($result, true); | ||
244 | + } | ||
245 | + curl_close($ch); | ||
246 | + $data = array(); | ||
247 | + | ||
248 | + return $result; | ||
249 | + } | ||
250 | + | ||
251 | + /** | ||
252 | + * 批量调用接口 | ||
253 | + * | ||
254 | + * @param array $urlList 接口列表 | ||
255 | + * @param array $options CURL设置项 | ||
256 | + * @parma mixed $cache 控制是否启用接口数据的缓存(时间单位为秒). 如3600表示缓存1小时, false表示不缓存 | ||
257 | + * @param int $timeout 超时时间,单位是秒 | ||
258 | + * @return array | ||
259 | + */ | ||
260 | + public static function getMulti($urlList = array(), $options = array(), $cache = false, $timeout = 5) | ||
261 | + { | ||
262 | + /* 开启缓存的情况 */ | ||
263 | + if ($cache && USE_CACHE) { | ||
264 | + $key = md5(implode(',', array_values($urlList))); | ||
265 | + // 先尝试获取一级缓存(master), 有数据则直接返回. | ||
266 | + $result = Cache::get($key, 'master'); | ||
267 | + if (!empty($result)) { | ||
268 | + return $result; | ||
269 | + } | ||
270 | + } | ||
271 | + | ||
272 | + $result = array(); | ||
273 | + $response = array(); | ||
274 | + $running = 0; | ||
275 | + $data = ''; | ||
276 | + $error = ''; | ||
277 | + $defaultOptions = array( | ||
278 | + CURLOPT_HEADER => 0, | ||
279 | + CURLOPT_RETURNTRANSFER => 1, | ||
280 | + CURLOPT_CONNECTTIMEOUT => $timeout, | ||
281 | + CURLOPT_TIMEOUT => $timeout, | ||
282 | + CURLOPT_NOSIGNAL => 1, //忽略所有的curl传递给php的信号,减少并发crash | ||
283 | + ); | ||
284 | + $mh = curl_multi_init(); | ||
285 | + $ch = array(); | ||
286 | + | ||
287 | + // 应用CURL配置 | ||
288 | + if (empty($options)) { | ||
289 | + $options = $defaultOptions; | ||
290 | + } else { | ||
291 | + $options = array_merge($defaultOptions, $options); | ||
292 | + } | ||
293 | + | ||
294 | + // 添加子链接句柄 | ||
295 | + foreach ($urlList as $name => $api) { | ||
296 | + $ch[$name] = curl_init($api); | ||
297 | + curl_setopt_array($ch[$name], $options); | ||
298 | + curl_multi_add_handle($mh, $ch[$name]); | ||
299 | + $result[$name] = array(); | ||
300 | + } | ||
301 | + | ||
302 | + // 调用API接口 | ||
303 | + do { | ||
304 | + do { | ||
305 | + $status = curl_multi_exec($mh, $running); | ||
306 | + } while ($status == CURLM_CALL_MULTI_PERFORM); | ||
307 | + | ||
308 | + if ($status != CURLM_OK) { | ||
309 | + break; | ||
310 | + } | ||
311 | + | ||
312 | + if ($running > 0) { | ||
313 | + curl_multi_select($mh, 0.5); | ||
314 | + } | ||
315 | + } while ($running); | ||
316 | + | ||
317 | + // 获取API接口响应的结果 | ||
318 | + foreach ($urlList as $name => $api) { | ||
319 | + $error = curl_error($ch[$name]); | ||
320 | + if ($error != '') { | ||
321 | + continue; | ||
322 | + } | ||
323 | + | ||
324 | + $data = curl_multi_getcontent($ch[$name]); | ||
325 | + if (!$data) { | ||
326 | + continue; | ||
327 | + } | ||
328 | + | ||
329 | + $response = json_decode($data, true); | ||
330 | + if (empty($response['data'])) { | ||
331 | + continue; | ||
332 | + } | ||
333 | + $result[$name] = $response['data']; | ||
334 | + | ||
335 | + curl_multi_remove_handle($mh, $ch[$name]); | ||
336 | + curl_close($ch[$name]); | ||
337 | + } | ||
338 | + curl_multi_close($mh); | ||
339 | + | ||
340 | + /* 开启缓存的情况 */ | ||
341 | + if ($cache && USE_CACHE) { | ||
342 | + // 接口调用异常时, 不害怕,从我们的二级缓存(slave)里再取数据. | ||
343 | + if (empty($result[$name])) { | ||
344 | + $result = Cache::get($key, 'slave'); | ||
345 | + } | ||
346 | + // 接口调用成功时,这里会设置一级(master)和二级(slave)的缓存数据. | ||
347 | + else { | ||
348 | + Cache::set($key, $result, $cache); | ||
349 | + } | ||
350 | + } | ||
351 | + | ||
352 | + return $result; | ||
353 | + } | ||
354 | + | ||
355 | + /** | ||
356 | + * rpc调用远程服务(YAR) | ||
357 | + * | ||
358 | + * @see http://php.net/manual/zh/yar-client.setopt.php | ||
359 | + * @param string $uri | ||
360 | + * @param string $method | ||
361 | + * @param array $parameters | ||
362 | + * @param mixed $cache 控制是否启用接口数据的缓存(时间单位为秒). 如3600表示缓存1小时, false表示不缓存 | ||
363 | + * @param int $timeout | ||
364 | + * @return array | ||
365 | + */ | ||
366 | + public static function yarClient($uri, $method, $parameters = array(), $cache = false, $timeout = 3000) | ||
367 | + { | ||
368 | + /* 开启缓存的情况 */ | ||
369 | + if ($cache && USE_CACHE) { | ||
370 | + $key = self::httpBuildQuery($uri . $method, $parameters); | ||
371 | + // 先尝试获取一级缓存(master), 有数据则直接返回. | ||
372 | + $result = Cache::get($key, 'master'); | ||
373 | + if (!empty($result)) { | ||
374 | + return $result; | ||
375 | + } | ||
376 | + } | ||
377 | + | ||
378 | + $client = new \Yar_Client($uri); | ||
379 | + $client->SetOpt(YAR_OPT_PACKAGER, 'php'); | ||
380 | + $client->SetOpt(YAR_OPT_TIMEOUT, $timeout); | ||
381 | + $client->SetOpt(YAR_OPT_CONNECT_TIMEOUT, $timeout); | ||
382 | + | ||
383 | + try { | ||
384 | + $result = call_user_func_array(array($client, $method), $parameters); | ||
385 | + } catch (\Exception $e) { | ||
386 | + $result = array(); | ||
387 | + } | ||
388 | + | ||
389 | + /* 开启缓存的情况 */ | ||
390 | + if ($cache && USE_CACHE) { | ||
391 | + // 接口调用异常时, 不害怕,从我们的二级缓存(slave)里再取数据. | ||
392 | + if (empty($result)) { | ||
393 | + $result = Cache::get($key, 'slave'); | ||
394 | + } | ||
395 | + // 接口调用成功时,这里会设置一级(master)和二级(slave)的缓存数据. | ||
396 | + else { | ||
397 | + Cache::set($key, $result, $cache); | ||
398 | + } | ||
399 | + } | ||
400 | + | ||
401 | + return $result; | ||
402 | + } | ||
403 | + | ||
404 | + /** | ||
405 | + * 并行(异步)调用远程服务 | ||
406 | + * | ||
407 | + * @see http://php.net/manual/zh/class.yar-concurrent-client.php | ||
408 | + * @param string $uri | ||
409 | + * @param string $method | ||
410 | + * @param array $parameter | ||
411 | + * @param callable $callback | ||
412 | + * @param int $timeout | ||
413 | + * @return void | ||
414 | + */ | ||
415 | + public static function yarConcurrentCall($uri, $method, $parameters, $callback, $timeout = 3000) | ||
416 | + { | ||
417 | + \Yar_Concurrent_Client::call($uri, $method, $parameters, $callback, null, array( | ||
418 | + YAR_OPT_PACKAGER => 'php', | ||
419 | + YAR_OPT_TIMEOUT => $timeout, | ||
420 | + YAR_OPT_CONNECT_TIMEOUT => $timeout | ||
421 | + )); | ||
422 | + } | ||
423 | + | ||
424 | + public static function yarConcurrentLoop($callback = null) | ||
425 | + { | ||
426 | + \Yar_Concurrent_Client::loop($callback); | ||
427 | + } | ||
428 | + | ||
429 | + /** | ||
430 | + * 提交json格式数据请求java有关接口 | ||
431 | + * | ||
432 | + * @param string $url 接口URL | ||
433 | + * @param array $data 参数列表 | ||
434 | + * @param bool $returnJson 控制是否返回json格式数据 | ||
435 | + * @param int $timeout 超时时间 | ||
436 | + * @param array $cookie | ||
437 | + * @return mixed | ||
438 | + */ | ||
439 | + public static function jsonPost($url, $data = array(), $returnJson = false, $timeout = 10, $cookie = array()) | ||
440 | + { | ||
441 | + $ch = curl_init($url); | ||
442 | + | ||
443 | + curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | ||
444 | + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); | ||
445 | + | ||
446 | + if (!empty($cookie)) { | ||
447 | + $cookie_str = array(); | ||
448 | + foreach ($cookie as $key => $val) { | ||
449 | + $cookie_str[] = urlencode($key) . '=' . urlencode($val); | ||
450 | + } | ||
451 | + curl_setopt($ch, CURLOPT_COOKIE, implode(';', $cookie_str)); | ||
452 | + } | ||
453 | + | ||
454 | + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
455 | + | ||
456 | + if (!empty($data)) { | ||
457 | + $data_string = json_encode($data); | ||
458 | + | ||
459 | + curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); | ||
460 | + // 设置json的Header | ||
461 | + curl_setopt($ch, CURLOPT_HTTPHEADER, array( | ||
462 | + 'Content-Type: application/json', | ||
463 | + 'Content-Length: ' . strlen($data_string) | ||
464 | + )); | ||
465 | + } | ||
466 | + $result = curl_exec($ch); | ||
467 | + if (!$returnJson && !empty($result)) { | ||
468 | + $result = json_decode($result, true); | ||
469 | + } | ||
470 | + curl_close($ch); | ||
471 | + $data = array(); | ||
472 | + | ||
473 | + return $result; | ||
474 | + } | ||
475 | + | ||
476 | +} |
-
Please register or login to post a comment