<?php
require_once(dirname(__FILE__) . '/BaiduUtils.php');
require_once(dirname(__FILE__) . '/BaiduException.php');
class BaiduApiClient
{
public static $BD_OPENAPI_DEFAULT_DOMAINS = array(
'public' => 'http://openapi.baidu.com',
'rest' => 'https://openapi.baidu.com',
'file' => 'https://openapi.baidu.com',
);
public static $BD_OPENAPI_DEFAULT_PREFIXS = array(
'public' => 'http://openapi.baidu.com/public/2.0/',
'rest' => 'https://openapi.baidu.com/rest/2.0/',
'file' => 'https://openapi.baidu.com/file/2.0/',
);
protected $clientId;
protected $accessToken;
protected $finalEncode = 'UTF-8';
protected $batchMode;
protected $batchQueue = null;
const BATCH_MODE_SERVER_PARALLEL = 0;
const BATCH_MODE_SERIAL_ONLY = 1;
public function __construct($clientId, $accessToken)
{
$this->clientId = $clientId;
$this->accessToken = $accessToken;
}
public function getClientId()
{
return $this->clientId;
}
public function setClientId($clientId)
{
$this->clientId = $clientId;
return $this;
}
public function getAccessToken()
{
return $this->accessToken;
}
public function setAccessToken($accessToken)
{
$this->accessToken = $accessToken;
return $this;
}
public function getFinalEncode()
{
return $this->finalEncode;
}
public function setFinalEncode($finalEncode)
{
$this->finalEncode = strtoupper($finalEncode);
return $this;
}
public function setBatchMode($batchMode)
{
$this->batchMode = $batchMode;
return $this;
}
public function beginBatch()
{
if ($this->batchQueue === null) {
$this->batchQueue = array();
}
}
public function end_batch()
{
if ($this->batchQueue !== null) {
$this->batchRun();
$this->batchQueue = null;
}
}
public function & api($uri, $params = array(), $httpMethod = 'GET', $type = 'rest')
{
if (substr($uri, 0, 8) === 'https://') {
$params = array_merge(array('access_token' => $this->getAccessToken()), $params);
} elseif (substr($uri, 0, 7) === 'http://') {
$params = array_merge(array('client_id' => $this->getClientId()), $params);
} else {
if (substr($uri, 0, 6) === '/rest/') {
$uri = self::$BD_OPENAPI_DEFAULT_DOMAINS['rest'] . $uri;
$params = array_merge(array('access_token' => $this->getAccessToken()), $params);
} elseif (substr($uri, 0, 8) === '/public/') {
$uri = self::$BD_OPENAPI_DEFAULT_DOMAINS['public'] . $uri;
$params = array_merge(array('client_id' => $this->getClientId()), $params);
} elseif ($type === 'rest') {
$uri = self::$BD_OPENAPI_DEFAULT_PREFIXS['rest'] . $uri;
$params = array_merge(array('access_token' => $this->getAccessToken()), $params);
} elseif ($type === 'public') {
$uri = self::$BD_OPENAPI_DEFAULT_PREFIXS['public'] . $uri;
$params = array_merge(array('client_id' => $this->getClientId()), $params);
} else {
BaiduUtils::setError(-1, 'Invalid params for ' . __METHOD__ . ": uri[$uri] type[$type]");
return false;
}
}
if ($this->batchQueue === null) {
$result = BaiduUtils::request($uri, $params, $httpMethod);
if ($result !== false) {
$result = $this->converJson2Array($result);
if (is_array($result) && isset($result['error_code'])) {
BaiduUtils::setError(-1, 'failed to call baidu openapi: error_code[' .
$result['error_code'] . '] error_msg[' . $result['error_msg'] . ']');
return false;
}
}
} else {
$result = null;
unset($params['access_token']);
unset($params['client_id']);
$query = http_build_query($params, '', '&');
$parts = parse_url($uri);
$item = array('domain' => $parts['host'],
'path' => $parts['path'],
'params' => $parts['query'] ? $parts['query'] . '&' . $query : $query,
'http_method' => $httpMethod);
if ($parts['scheme'] === 'https') {
$this->batchQueue[0][] = array('i' => $item, 'r' => & $result);
} else {
$this->batchQueue[1][] = array('i' => $item, 'r' => & $result);
}
}
return $result;
}
public function upload($uri, $params = array())
{
$params = array_merge(array('access_token' => $this->getAccessToken()), $params);
if (substr($uri, 0, 8) === 'https://' || substr($uri, 0, 7) === 'http://') {
} elseif (substr($uri, 0, 6) === '/file/') {
$uri = self::$BD_OPENAPI_DEFAULT_DOMAINS['file'] . $uri;
} else {
$uri = self::$BD_OPENAPI_DEFAULT_PREFIXS['file'] . $uri;
}
$result = BaiduUtils::request($uri, $params, 'POST', true);
if ($result !== false) {
$result = $this->converJson2Array($result);
if (is_array($result) && isset($result['error_code'])) {
BaiduUtils::setError(-1, 'failed to call baidu openapi: error_code[' .
$result['error_code'] . '] error_msg[' . $result['error_msg'] . ']');
return false;
}
}
return $result;
}
public static function iconv($var, $inCharset = 'UTF-8', $outCharset = 'GBK')
{
if (is_array($var)) {
$rvar = array();
foreach ($var as $key => $val) {
$rvar[$key] = self::iconv($val, $inCharset, $outCharset);
}
return $rvar;
} elseif (is_object($var)) {
$rvar = null;
foreach ($var as $key => $val) {
$rvar->{$key} = self::iconv($val, $inCharset, $outCharset);
}
return $rvar;
} elseif (is_string($var)) {
return iconv($inCharset, $outCharset, $var);
} else {
return $var;
}
}
private function batchRun()
{
$this->doBatchRun(true);
$this->doBatchRun(false);
}
private function doBatchRun($useHttps = true)
{
$batchQueue = $this->batchQueue[$useHttps ? 0 : 1];
if (empty($batchQueue)) {
return;
}
$num = count($batchQueue);
$params = array();
foreach ($batchQueue as $item) {
$params[] = $item['i'];
}
$json = json_encode($params);
$serialOnly = ($this->batchMode === self::BATCH_MODE_SERIAL_ONLY);
$params = array('method' => $json, 'serial_only' => $serialOnly);
if ($useHttps) {
$params['access_token'] = $this->getAccessToken();
$domain = self::$BD_OPENAPI_DEFAULT_DOMAINS['rest'];
} else {
$params['client_id'] = $this->getClientId();
$domain = self::$BD_OPENAPI_DEFAULT_DOMAINS['public'];
}
$result = BaiduUtils::request($domain . '/batch/run', $params, 'POST');
if ($result === false) {
throw new BaiduException('failed to call batch/run api: ' .
BaiduUtils::errmsg(), BaiduUtils::errno());
}
$result = $this->converJson2Array($result);
if (is_array($result) && isset($result['error_code'])) {
throw new BaiduException('failed to call batch/run api: ' .
$result['error_msg'], $result['error_code']);
}
for ($i = 0; $i < $num; $i++) {
$item = $batchQueue[$i];
$itemResult = $result[$i];
if (is_array($itemResult) && isset($itemResult['error_code'])) {
throw new BaiduException('failed to call ' . $item['i']['path'] . ' api: ' .
$itemResult['error_msg'], $itemResult['error_code']);
}
$item['r'] = $itemResult;
}
}
private function converJson2Array($json)
{
$result = json_decode($json, true);
if (strcasecmp($this->finalEncode, 'UTF-8') !== 0) {
$result = self::iconv($result, 'UTF-8', $this->finalEncode);
}
return $result;
}
}