Yohobuy.php 6.94 KB
<?php

/**
 * 有货相关接口类
 * 
 * @name Yohobuy
 * @package library/Api
 * @copyright yoho.inc
 * @version 1.0 (2015-9-30 16:42:51)
 * @author fei.hong <fei.hong@yoho.cn>
 */
namespace Api;

class Yohobuy
{
    const API_URL = 'http://api2.open.yohobuy.com/';
    const SERVICE_URL = 'http://service.api.yohobuy.com/';

    /**
     * 私钥列表
     * 
     * @var array 
     */
    private static $privateKeyList = array(
        'android' => 'fd4ad5fcfa0de589ef238c0e7331b585',
        'iphone' => 'a85bb0674e08986c6b115d5e3a4884fa',
        'ipad' => 'ad9fcda2e679cf9229e37feae2cdcf80',
    );
    
    /**
     * 取得当前的客户端类型
     */
    public static function clientType() 
    {
        // 苹果设备
        if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone')) {
            return 'iphone';
        }
        // 苹果IPAD
        elseif (strstr($_SERVER['HTTP_USER_AGENT'], 'iPad')) {
            return 'ipad';
        }
        // 其它
        else {
            return 'android';
        }
    }
    
    /**
     * 取得公共的参数
     * 
     * @return array
     */
    public static function param()
    {
        $clientType = self::clientType();
        $param = array(
            'app_version' => '3.6',
            'client_type' => $clientType,
            'os_version' => 'yohobuy:h5',
            'private_key' => self::$privateKeyList[$clientType],
            'screen_size' => '720x1280',
            'v' => '6',
        );
        return $param;
    }
    
    /**
     * 构建URL
     * 
     * @param string $url
     * @param array $data
     * @return string
     */
    public static function httpBuildQuery($url, $data)
    {
        if (strstr($url, '?') !== false) {
            $url .= '&' . http_build_query($data, null, '&');
        } else {
            $url .= '?' . http_build_query($data, null, '&');
        }
        return $url;
    }
    
    /**
     * get方式调用接口
     * 
     * @param string $url 接口URL
     * @param array $data 参数列表
     * @param bool $returnJson 控制是否返回json格式数据
     * @param int $timeout 超时时间
     * @return mixed
     */
    public static function get($url, $data = array(), $returnJson = false, $timeout = 5)
    {
        if (isset($data['private_key'])) {
            unset($data['private_key']);
        }
        if (!empty($data)) {
            $url = self::httpBuildQuery($url, $data);
        }
        
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);
        if (!$returnJson && !empty($result)) {
            $result = json_decode($result, true);
        }
        curl_close($ch);
        $data = array();

        return $result;
    }

    /**
     * post提交数据
     * 
     * @param string $url 接口URL
     * @param array $data 参数列表
     * @param bool $returnJson 控制是否返回json格式数据
     * @param int $timeout 超时时间
     * @param array $header
     * @param array $cookie
     * @return mixed
     */
    public static function post($url, $data = array(), $returnJson = false, $timeout = 5, $header = array(), $cookie = array())
    {
        $ch = curl_init($url);
        
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        if (!empty($header)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        } else {
            curl_setopt($ch, CURLOPT_HEADER, 0);
        }

        if (!empty($cookie)) {
            $cookie_str = array();
            foreach ($cookie as $key => $val) {
                $cookie_str[] = urlencode($key) . '=' . urlencode($val);
            }
            curl_setopt($ch, CURLOPT_COOKIE, implode(';', $cookie_str));
        }

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        if (isset($data['private_key'])) {
            unset($data['private_key']);
        }
        if (!empty($data)) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }
        $result = curl_exec($ch);
        if (!$returnJson && !empty($result)) {
            $result = json_decode($result, true);
        }
        curl_close($ch);
        $data = array();
        
        return $result;
    }

    /**
     * 批量调用接口
     * 
     * @param array $urlList 接口列表
     * @param array $options CURL设置项
     * @return array
     */
    public function loop($urlList = array(), $options = array())
    {
        $result = array();
        $response = array();
        $running = null;
        $data = '';
        $error = '';
        $defaultOptions = array(
            CURLOPT_HEADER => 0,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_CONNECTTIMEOUT => 5,
            CURLOPT_TIMEOUT => 5,
        );
        $mh = curl_multi_init();
        $ch = array();

        // 应用CURL配置
        if (empty($options)) {
            $options = $defaultOptions;
        } else {
            $options = array_merge($defaultOptions, $options);
        }

        // 添加子链接句柄
        foreach ($urlList as $name => $api) {
            $ch[$name] = curl_init($api);
            curl_setopt_array($ch[$name], $options);
            curl_multi_add_handle($mh, $ch[$name]);
            $result[$name] = array();
        }

        // 调用API接口
        do {
            $status = curl_multi_exec($mh, $running);
        }
        while ($status == CURLM_CALL_MULTI_PERFORM);
        while ($running && $status == CURLM_OK) {
            if (curl_multi_select($mh, 0.5) != -1) {
                do {
                    $status = curl_multi_exec($mh, $running);
                }
                while ($status == CURLM_CALL_MULTI_PERFORM);
            }
        }

        // 获取API接口响应的结果
        foreach ($urlList as $name => $api) {
            $error = curl_error($ch[$name]);
            if ($error != '') {
                continue;
            }

            $data = curl_multi_getcontent($ch[$name]);
            if (!$data) {
                continue;
            }

            $response = json_decode($data, true);
            if (empty($response['data'])) {
                continue;
            }
            $result[$name] = $response['data'];

            curl_multi_remove_handle($mh, $ch[$name]);
            curl_close($ch[$name]);
        }
        curl_multi_close($mh);
        
        return $result;
    }
    
    /**
     * rpc调用远程服务(YAR)
     * 
     * @see http://php.net/manual/zh/yar-client.setopt.php
     * @return array
     */
    public static function yarClient($uri, $method, $data = array(), $timeout = 3000)
    {
        $client = new \Yar_Client($uri);
        $client->SetOpt(YAR_OPT_PACKAGER, 'php');
        $client->SetOpt(YAR_OPT_TIMEOUT, $timeout);
        $client->SetOpt(YAR_OPT_CONNECT_TIMEOUT, $timeout);
        
        $result = $client->$method($data);
        
        return $result;
    }

}