使用示例:
```
* $rs = PhalApiClient::create()
* ->withHost('http://demo.phalapi.net/')
* ->withService('Default.Index')
* ->withParams('name', 'dogstar')
* ->withTimeout(3000)
* ->request();
*
* var_dump($rs->getRet(), $rs->getData(), $rs->getMsg());
```
*
* @package PhalApi\SDK
* @license http://www.phalapi.net/license GPL 协议
* @link http://www.phalapi.net/
* @author dogstar 2015-10-16
*/
class PhalApiClient {
protected $host;
protected $filter;
protected $parser;
protected $service;
protected $timeoutMs;
protected $params = array();
/**
* 创建一个接口实例,注意:不是单例模式
* @return PhalApiClient
*/
public static function create() {
return new self();
}
protected function __construct() {
$this->host = "";
$this->parser = new PhalApiClientParserJson();
}
/**
* 设置接口域名
* @param string $host
* @return PhalApiClient
*/
public function withHost($host) {
$this->host = $host;
return $this;
}
/**
* 设置过滤器,与服务器的DI()->filter对应
* @param PhalApiClientFilter $filter 过滤器
* @return PhalApiClient
*/
public function withFilter(PhalApiClientFilter $filter) {
$this->filter = $filter;
return $this;
}
/**
* 设置结果解析器,仅当不是JSON返回格式时才需要设置
* @param PhalApiClientParser $parser 结果解析器
* @return PhalApiClient
*/
public function withParser(PhalApiClientParser $parser) {
$this->parser = $parser;
return $this;
}
/**
* 重置,将接口服务名称、接口参数、请求超时进行重置,便于重复请求
* @return PhalApiClient
*/
public function reset() {
$this->service = "";
$this->timeoutMs = 3000;
$this->params = array();
return $this;
}
/**
* 设置将在调用的接口服务名称,如:Default.Index
* @param string $service 接口服务名称
* @return PhalApiClient
*/
public function withService($service) {
$this->service = $service;
return $this;
}
/**
* 设置接口参数,此方法是唯一一个可以多次调用并累加参数的操作
* @param string $name 参数名字
* @param string $value 值
* @return PhalApiClient
*/
public function withParams($name, $value) {
$this->params[$name] = $value;
return $this;
}
/**
* 设置超时时间,单位毫秒
* @param int $timeoutMs 超时时间,单位毫秒
* @return PhalApiClient
*/
public function withTimeout($timeoutMs) {
$this->timeoutMs = $timeoutMs;
return $this;
}
/**
* 发起接口请求
* @return PhalApiClientResponse
*/
public function request() {
$url = $this->host;
if (!empty($this->service)) {
$url .= '?service=' . $this->service;
}
if ($this->filter !== null) {
$this->filter->filter($this->service, $this->params);
}
$rs = $this->doRequest($url, $this->params, $this->timeoutMs);
return $this->parser->parse($rs);
}
protected function doRequest($url, $data, $timeoutMs = 3000)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $timeoutMs);
if (!empty($data)) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
$rs = curl_exec($ch);
curl_close($ch);
return $rs;
}
}
/**
* 接口返回结果
*
* - 与接口返回的格式对应,即有:ret/data/msg
*/
class PhalApiClientResponse {
protected $ret = 200;
protected $data = array();
protected $msg = '';
public function __construct($ret, $data = array(), $msg = '') {
$this->ret = $ret;
$this->data = $data;
$this->msg = $msg;
}
public function getRet() {
return $this->ret;
}
public function getData() {
return $this->data;
}
public function getMsg() {
return $this->msg;
}
}
/**
* 接口过滤器
*
* - 可用于接口签名生成
*/
interface PhalApiClientFilter {
/**
* 过滤操作
* @param string $service 接口服务名称
* @param array $params 接口参数,注意是引用。可以直接修改
* @return null
*/
public function filter($service, array &$params);
}
/**
* 接口结果解析器
*
* - 可用于不同接口返回格式的处理
*/
interface PhalApiClientParser {
/**
* 结果解析
* @param string $apiResult
* @return PhalApiClientResponse
*/
public function parse($apiResult);
}
/**
* JSON解析
*/
class PhalApiClientParserJson implements PhalApiClientParser {
public function parse($apiResult) {
if ($apiResult === false) {
return new PhalApiClientResponse(408, array(), 'Request Timeout');
}
$arr = json_decode($apiResult, true);
if ($arr === false || empty($arr)) {
return new PhalApiClientResponse(500, array(), 'Internal Server Error');
}
return new PhalApiClientResponse($arr['ret'], $arr['data'], $arr['msg']);
}
}