Authored by whb

PC重构

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 +}