Authored by hf

do modify call yohobuy api add yar corncurrent loop

@@ -13,6 +13,7 @@ namespace Api; @@ -13,6 +13,7 @@ namespace Api;
13 13
14 class Yohobuy 14 class Yohobuy
15 { 15 {
  16 +
16 const API_URL = 'http://api2.open.yohobuy.com/'; 17 const API_URL = 'http://api2.open.yohobuy.com/';
17 const SERVICE_URL = 'http://service.api.yohobuy.com/'; 18 const SERVICE_URL = 'http://service.api.yohobuy.com/';
18 19
@@ -26,11 +27,11 @@ class Yohobuy @@ -26,11 +27,11 @@ class Yohobuy
26 'iphone' => 'a85bb0674e08986c6b115d5e3a4884fa', 27 'iphone' => 'a85bb0674e08986c6b115d5e3a4884fa',
27 'ipad' => 'ad9fcda2e679cf9229e37feae2cdcf80', 28 'ipad' => 'ad9fcda2e679cf9229e37feae2cdcf80',
28 ); 29 );
29 - 30 +
30 /** 31 /**
31 * 取得当前的客户端类型 32 * 取得当前的客户端类型
32 */ 33 */
33 - public static function clientType() 34 + public static function clientType()
34 { 35 {
35 // 苹果设备 36 // 苹果设备
36 if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone')) { 37 if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone')) {
@@ -45,7 +46,7 @@ class Yohobuy @@ -45,7 +46,7 @@ class Yohobuy
45 return 'android'; 46 return 'android';
46 } 47 }
47 } 48 }
48 - 49 +
49 /** 50 /**
50 * 取得公共的参数 51 * 取得公共的参数
51 * 52 *
@@ -64,7 +65,7 @@ class Yohobuy @@ -64,7 +65,7 @@ class Yohobuy
64 ); 65 );
65 return $param; 66 return $param;
66 } 67 }
67 - 68 +
68 /** 69 /**
69 * 构建URL 70 * 构建URL
70 * 71 *
@@ -74,6 +75,10 @@ class Yohobuy @@ -74,6 +75,10 @@ class Yohobuy
74 */ 75 */
75 public static function httpBuildQuery($url, $data) 76 public static function httpBuildQuery($url, $data)
76 { 77 {
  78 + // 销毁私钥参数
  79 + if (isset($data['private_key'])) {
  80 + unset($data['private_key']);
  81 + }
77 if (strstr($url, '?') !== false) { 82 if (strstr($url, '?') !== false) {
78 $url .= '&' . http_build_query($data, null, '&'); 83 $url .= '&' . http_build_query($data, null, '&');
79 } else { 84 } else {
@@ -81,7 +86,7 @@ class Yohobuy @@ -81,7 +86,7 @@ class Yohobuy
81 } 86 }
82 return $url; 87 return $url;
83 } 88 }
84 - 89 +
85 /** 90 /**
86 * get方式调用接口 91 * get方式调用接口
87 * 92 *
@@ -93,13 +98,14 @@ class Yohobuy @@ -93,13 +98,14 @@ class Yohobuy
93 */ 98 */
94 public static function get($url, $data = array(), $returnJson = false, $timeout = 5) 99 public static function get($url, $data = array(), $returnJson = false, $timeout = 5)
95 { 100 {
  101 + // 销毁私钥参数
96 if (isset($data['private_key'])) { 102 if (isset($data['private_key'])) {
97 unset($data['private_key']); 103 unset($data['private_key']);
98 } 104 }
99 if (!empty($data)) { 105 if (!empty($data)) {
100 $url = self::httpBuildQuery($url, $data); 106 $url = self::httpBuildQuery($url, $data);
101 } 107 }
102 - 108 +
103 $ch = curl_init($url); 109 $ch = curl_init($url);
104 curl_setopt($ch, CURLOPT_HEADER, 0); 110 curl_setopt($ch, CURLOPT_HEADER, 0);
105 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); 111 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
@@ -128,11 +134,12 @@ class Yohobuy @@ -128,11 +134,12 @@ class Yohobuy
128 public static function post($url, $data = array(), $returnJson = false, $timeout = 5, $header = array(), $cookie = array()) 134 public static function post($url, $data = array(), $returnJson = false, $timeout = 5, $header = array(), $cookie = array())
129 { 135 {
130 $ch = curl_init($url); 136 $ch = curl_init($url);
131 - 137 +
132 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); 138 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
133 if (!empty($header)) { 139 if (!empty($header)) {
134 curl_setopt($ch, CURLOPT_HTTPHEADER, $header); 140 curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
135 - } else { 141 + }
  142 + else {
136 curl_setopt($ch, CURLOPT_HEADER, 0); 143 curl_setopt($ch, CURLOPT_HEADER, 0);
137 } 144 }
138 145
@@ -146,6 +153,7 @@ class Yohobuy @@ -146,6 +153,7 @@ class Yohobuy
146 153
147 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 154 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
148 curl_setopt($ch, CURLOPT_POST, true); 155 curl_setopt($ch, CURLOPT_POST, true);
  156 + // 销毁私钥参数
149 if (isset($data['private_key'])) { 157 if (isset($data['private_key'])) {
150 unset($data['private_key']); 158 unset($data['private_key']);
151 } 159 }
@@ -158,7 +166,7 @@ class Yohobuy @@ -158,7 +166,7 @@ class Yohobuy
158 } 166 }
159 curl_close($ch); 167 curl_close($ch);
160 $data = array(); 168 $data = array();
161 - 169 +
162 return $result; 170 return $result;
163 } 171 }
164 172
@@ -173,14 +181,15 @@ class Yohobuy @@ -173,14 +181,15 @@ class Yohobuy
173 { 181 {
174 $result = array(); 182 $result = array();
175 $response = array(); 183 $response = array();
176 - $running = null; 184 + $running = 0;
177 $data = ''; 185 $data = '';
178 $error = ''; 186 $error = '';
179 $defaultOptions = array( 187 $defaultOptions = array(
180 CURLOPT_HEADER => 0, 188 CURLOPT_HEADER => 0,
181 CURLOPT_RETURNTRANSFER => 1, 189 CURLOPT_RETURNTRANSFER => 1,
182 - CURLOPT_CONNECTTIMEOUT => 5,  
183 - CURLOPT_TIMEOUT => 5, 190 + CURLOPT_CONNECTTIMEOUT => 3,
  191 + CURLOPT_TIMEOUT => 3,
  192 + CURLOPT_NOSIGNAL => 1, //忽略所有的curl传递给php的信号,减少并发crash
184 ); 193 );
185 $mh = curl_multi_init(); 194 $mh = curl_multi_init();
186 $ch = array(); 195 $ch = array();
@@ -201,17 +210,21 @@ class Yohobuy @@ -201,17 +210,21 @@ class Yohobuy
201 } 210 }
202 211
203 // 调用API接口 212 // 调用API接口
204 - do {  
205 - $status = curl_multi_exec($mh, $running);  
206 - }  
207 - while ($status == CURLM_CALL_MULTI_PERFORM);  
208 - while ($running && $status == CURLM_OK) {  
209 - if (curl_multi_select($mh, 0.5) > -1) {  
210 - do {  
211 - $status = curl_multi_exec($mh, $running);  
212 - } while ($status == CURLM_CALL_MULTI_PERFORM);  
213 - } 213 + do {
  214 + do {
  215 + $status = curl_multi_exec($mh, $running);
  216 + }
  217 + while ($status == CURLM_CALL_MULTI_PERFORM);
  218 +
  219 + if ($status != CURLM_OK) {
  220 + break;
  221 + }
  222 +
  223 + if ($running > 0) {
  224 + curl_multi_select($mh, 0.5);
  225 + }
214 } 226 }
  227 + while ($running);
215 228
216 // 获取API接口响应的结果 229 // 获取API接口响应的结果
217 foreach ($urlList as $name => $api) { 230 foreach ($urlList as $name => $api) {
@@ -235,26 +248,49 @@ class Yohobuy @@ -235,26 +248,49 @@ class Yohobuy
235 curl_close($ch[$name]); 248 curl_close($ch[$name]);
236 } 249 }
237 curl_multi_close($mh); 250 curl_multi_close($mh);
238 - 251 +
239 return $result; 252 return $result;
240 } 253 }
241 - 254 +
242 /** 255 /**
243 * rpc调用远程服务(YAR) 256 * rpc调用远程服务(YAR)
244 * 257 *
245 * @see http://php.net/manual/zh/yar-client.setopt.php 258 * @see http://php.net/manual/zh/yar-client.setopt.php
246 * @return array 259 * @return array
247 */ 260 */
248 - public static function yarClient($uri, $method, $data = array(), $timeout = 3000) 261 + public static function yarClient($uri, $method, $parameters = array(), $timeout = 3000)
249 { 262 {
250 $client = new \Yar_Client($uri); 263 $client = new \Yar_Client($uri);
251 $client->SetOpt(YAR_OPT_PACKAGER, 'php'); 264 $client->SetOpt(YAR_OPT_PACKAGER, 'php');
252 $client->SetOpt(YAR_OPT_TIMEOUT, $timeout); 265 $client->SetOpt(YAR_OPT_TIMEOUT, $timeout);
253 $client->SetOpt(YAR_OPT_CONNECT_TIMEOUT, $timeout); 266 $client->SetOpt(YAR_OPT_CONNECT_TIMEOUT, $timeout);
254 -  
255 - $result = $client->$method($data);  
256 - 267 + $result = $client->$method($parameters);
  268 +
257 return $result; 269 return $result;
258 } 270 }
  271 +
  272 + /**
  273 + * 并行(异步)调用远程服务
  274 + *
  275 + * @see http://php.net/manual/zh/class.yar-concurrent-client.php
  276 + * @param string $uri
  277 + * @param string $method
  278 + * @param array $parameter
  279 + * @param callable $callback
  280 + * @param int $timeout
  281 + * @return void
  282 + */
  283 + public static function yarConcurrentCall($uri, $method, $parameters, $callback, $timeout = 3000)
  284 + {
  285 + \Yar_Concurrent_Client::call($uri, $method, array($parameters), $callback, null, array(
  286 + YAR_OPT_PACKAGER => 'php',
  287 + YAR_OPT_TIMEOUT => $timeout,
  288 + YAR_OPT_CONNECT_TIMEOUT => $timeout
  289 + ));
  290 + }
  291 + public static function yarConcurrentLoop($callback = null)
  292 + {
  293 + \Yar_Concurrent_Client::loop($callback);
  294 + }
259 295
260 } 296 }
1 <?php 1 <?php
2 -use Action\AbstractAction; 2 +
  3 +namespace LibModels\Wap\Guang;
  4 +
  5 +use Api\Sign;
  6 +use Api\Yohobuy;
  7 +
3 /** 8 /**
4 - * 明星品牌和原创品牌 9 + * 明星品牌和原创品牌相关的数据模型
  10 + *
  11 + * @name PlusstarData
  12 + * @package Library/LibModels/Wap/Guang
  13 + * @copyright yoho.inc
  14 + * @version 1.0 (2015-10-9 10:22:10)
  15 + * @author fei.hong <fei.hong@yoho.cn>
5 */ 16 */
6 -class PlusstarController extends AbstractAction 17 +class PlusstarData
7 { 18 {
8 - 19 +
9 /** 20 /**
10 - * 品牌列表页 21 + * 品牌列表
  22 + *
  23 + * @param string $gender "1,3"表示男, "2,3"表示女
  24 + * @param string $channel 1表示男, 2表示女
  25 + * @return array(
  26 + * "star" => array(明星品牌列表数据),
  27 + * "original" => array(原创品牌列表数据)
  28 + * )
11 */ 29 */
12 - public function listAction() 30 + public static function brandList($gender, $channel)
13 { 31 {
14 - $this->_view->assign('title', 'YOHO!有货');  
15 - $this->_view->display('list', array('test' => 'hello world')); 32 + // 存放接口列表
  33 + $urlList = array();
  34 + // 接口调用的URL
  35 + $url = Yohobuy::SERVICE_URL . 'guang/api/v1/plustar/getlist';
  36 +
  37 + // 公共的参数
  38 + $param = Yohobuy::param();
  39 + $param['gender'] = $gender;
  40 + $param['is_recommend'] = '0';
  41 + $param['yh_channel'] = $channel;
  42 +
  43 + // 构建明星品牌参数及调用接口的URL
  44 + $star = $param;
  45 + $star['brand_type'] = '2';
  46 + $star['client_secret'] = Sign::getSign($star);
  47 + $urlList['star'] = Yohobuy::httpBuildQuery($url, $star);
  48 +
  49 + // 构建原创品牌参数及调用接口的URL
  50 + $original = $param;
  51 + $original['brand_type'] = '3';
  52 + $original['client_secret'] = Sign::getSign($original);
  53 + $urlList['original'] = Yohobuy::httpBuildQuery($url, $original);
  54 +
  55 + return Yohobuy::getMulti($urlList);
16 } 56 }
17 - 57 +
18 /** 58 /**
19 - * 品牌介绍 59 + * 品牌介绍
20 */ 60 */
21 - public function detailAction() 61 + public static function brandInfo($id)
22 { 62 {
  63 + $result = array();
  64 +
  65 + Yohobuy::yarConcurrentCall('http://service.api.yohobuy.com/guang/service/v1/plustar/', 'getBrandInfo', array('id' => 289), function($retval, $callinfo) use(&$result) {
  66 + $result[ $callinfo['method'] ] = empty($retval['data']) ? array() : $retval['data'];
  67 + });
  68 + Yohobuy::yarConcurrentCall('http://service.api.yohobuy.com/guang/service/v1/plustar/', 'getList', array('id' => 289), function($retval, $callinfo) use(&$result) {
  69 + $result[ $callinfo['method'] ] = empty($retval['data']) ? array() : $retval['data'];
  70 + });
  71 + Yohobuy::yarConcurrentLoop();
23 72
  73 + return $result;
24 } 74 }
25 -  
26 -}  
  75 +
  76 +}
1 <?php 1 <?php
2 -namespace LibModels\wap\Channel; 2 +namespace LibModels\Wap\Product;
3 3
4 use Api\Yohobuy; 4 use Api\Yohobuy;
5 use Api\Sign; 5 use Api\Sign;
@@ -60,7 +60,7 @@ class NewsaleData @@ -60,7 +60,7 @@ class NewsaleData
60 $urlList['week'] = Yohobuy::httpBuildQuery(Yohobuy::API_URL,$param); 60 $urlList['week'] = Yohobuy::httpBuildQuery(Yohobuy::API_URL,$param);
61 $param['dayLimit'] = 3; 61 $param['dayLimit'] = 3;
62 $urlList['sale'] = Yohobuy::httpBuildQuery(Yohobuy::API_URL,$param); 62 $urlList['sale'] = Yohobuy::httpBuildQuery(Yohobuy::API_URL,$param);
63 - // var_dump($urlList);exit; 63 + //var_dump($urlList);exit;
64 64
65 return Yohobuy::getMulti($urlList); 65 return Yohobuy::getMulti($urlList);
66 } 66 }
1 <?php 1 <?php
2 use Action\AbstractAction; 2 use Action\AbstractAction;
3 -use Api\Yohobuy; 3 +use LibModels\Wap\Guang\PlusstarData;
4 4
5 /** 5 /**
6 * 频道选择 6 * 频道选择
@@ -12,6 +12,7 @@ class IndexController extends AbstractAction @@ -12,6 +12,7 @@ class IndexController extends AbstractAction
12 $this->_view->assign('title', 'YOHO!有货'); 12 $this->_view->assign('title', 'YOHO!有货');
13 $this->_view->display('index', array('test' => 'hello world')); 13 $this->_view->display('index', array('test' => 'hello world'));
14 14
15 - //$test = Yohobuy::yarClient('http://service.api.yohobuy.com/guang/service/v1/plustar/', 'getBrandInfo', array('id' => 289)); 15 + $test = PlusstarData::brandInfo();
  16 + var_dump($test);
16 } 17 }
17 } 18 }
1 <?php 1 <?php
2 2
3 use Action\AbstractAction; 3 use Action\AbstractAction;
4 -use LibModels\wap\Channel\NewsaleData as Newsale; 4 +use LibModels\wap\Product\NewsaleData as Newsale;
5 use Plugin\Helpers; 5 use Plugin\Helpers;
6 /** 6 /**
7 * 新品到着 7 * 新品到着