php topclient,extend/taobao/top/TopClient.php · baobaof/taobaocms - Gitee.com

namespace taobao\top;

use \Exception;

class TopClient

{

public $appkey;

public $secretKey;

public $gatewayUrl = "http://gw.api.taobao.com/router/rest";

public $format = "xml";

public $connectTimeout;

public $readTimeout;

/** 是否打开入参check**/

public $checkRequest = true;

protected $signMethod = "md5";

protected $apiVersion = "2.0";

protected $sdkVersion = "top-sdk-php-20151012";

public function __construct($appkey = "",$secretKey = ""){

$this->appkey = $appkey;

$this->secretKey = $secretKey ;

}

protected function generateSign($params)

{

ksort($params);

$stringToBeSigned = $this->secretKey;

foreach ($params as $k => $v)

{

if(is_string($v) && "@" != substr($v, 0, 1))

{

$stringToBeSigned .= "$k$v";

}

}

unset($k, $v);

$stringToBeSigned .= $this->secretKey;

return strtoupper(md5($stringToBeSigned));

}

public function curl($url, $postFields = null)

{

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_FAILONERROR, false);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

if ($this->readTimeout) {

curl_setopt($ch, CURLOPT_TIMEOUT, $this->readTimeout);

}

if ($this->connectTimeout) {

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectTimeout);

}

curl_setopt ( $ch, CURLOPT_USERAGENT, "top-sdk-php" );

//https 请求

if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

}

if (is_array($postFields) && 0 < count($postFields))

{

$postBodyString = "";

$postMultipart = false;

foreach ($postFields as $k => $v)

{

if(!is_string($v))

continue ;

if("@" != substr($v, 0, 1))//判断是不是文件上传

{

$postBodyString .= "$k=" . urlencode($v) . "&";

}

else//文件上传用multipart/form-data,否则用www-form-urlencoded

{

$postMultipart = true;

if(class_exists('\CURLFile')){

$postFields[$k] = new \CURLFile(substr($v, 1));

}

}

}

unset($k, $v);

curl_setopt($ch, CURLOPT_POST, true);

if ($postMultipart)

{

if (class_exists('\CURLFile')) {

curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);

} else {

if (defined('CURLOPT_SAFE_UPLOAD')) {

curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);

}

}

curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);

}

else

{

$header = array("content-type: application/x-www-form-urlencoded; charset=UTF-8");

curl_setopt($ch,CURLOPT_HTTPHEADER,$header);

curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString,0,-1));

}

}

$reponse = curl_exec($ch);

if (curl_errno($ch))

{

throw new Exception(curl_error($ch),0);

}

else

{

$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if (200 !== $httpStatusCode)

{

throw new Exception($reponse,$httpStatusCode);

}

}

curl_close($ch);

return $reponse;

}

public function curl_with_memory_file($url, $postFields = null, $fileFields = null)

{

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_FAILONERROR, false);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

if ($this->readTimeout) {

curl_setopt($ch, CURLOPT_TIMEOUT, $this->readTimeout);

}

if ($this->connectTimeout) {

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectTimeout);

}

curl_setopt ( $ch, CURLOPT_USERAGENT, "top-sdk-php" );

//https 请求

if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

}

//生成分隔符

$delimiter = '-------------' . uniqid();

//先将post的普通数据生成主体字符串

$data = '';

if($postFields != null){

foreach ($postFields as $name => $content) {

$data .= "--" . $delimiter . "\r\n";

$data .= 'Content-Disposition: form-data; name="' . $name . '"';

//multipart/form-data 不需要urlencode,参见 http:stackoverflow.com/questions/6603928/should-i-url-encode-post-data

$data .= "\r\n\r\n" . $content . "\r\n";

}

unset($name,$content);

}

//将上传的文件生成主体字符串

if($fileFields != null){

foreach ($fileFields as $name => $file) {

$data .= "--" . $delimiter . "\r\n";

$data .= 'Content-Disposition: form-data; name="' . $name . '"; filename="' . $file['name'] . "\" \r\n";

$data .= 'Content-Type: ' . $file['type'] . "\r\n\r\n";//多了个文档类型

$data .= $file['content'] . "\r\n";

}

unset($name,$file);

}

//主体结束的分隔符

$data .= "--" . $delimiter . "--";

curl_setopt($ch, CURLOPT_POST, true);

curl_setopt($ch, CURLOPT_HTTPHEADER , array(

'Content-Type: multipart/form-data; boundary=' . $delimiter,

'Content-Length: ' . strlen($data))

);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

$reponse = curl_exec($ch);

unset($data);

if (curl_errno($ch))

{

throw new Exception(curl_error($ch),0);

}

else

{

$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if (200 !== $httpStatusCode)

{

throw new Exception($reponse,$httpStatusCode);

}

}

curl_close($ch);

return $reponse;

}

protected function logCommunicationError($apiName, $requestUrl, $errorCode, $responseTxt)

{

$localIp = isset($_SERVER["SERVER_ADDR"]) ? $_SERVER["SERVER_ADDR"] : "CLI";

$logger = new TopLogger;

$logger->conf["log_file"] = rtrim(TOP_SDK_WORK_DIR, '\\/') . '/' . "logs/top_comm_err_" . $this->appkey . "_" . date("Y-m-d") . ".log";

$logger->conf["separator"] = "^_^";

$logData = array(

date("Y-m-d H:i:s"),

$apiName,

$this->appkey,

$localIp,

PHP_OS,

$this->sdkVersion,

$requestUrl,

$errorCode,

str_replace("\n","",$responseTxt)

);

$logger->log($logData);

}

public function execute($request, $session = null,$bestUrl = null)

{

$result = new ResultSet();

if($this->checkRequest) {

try {

$request->check();

} catch (Exception $e) {

$result->code = $e->getCode();

$result->msg = $e->getMessage();

return $result;

}

}

//组装系统参数

$sysParams["app_key"] = $this->appkey;

$sysParams["v"] = $this->apiVersion;

$sysParams["format"] = $this->format;

$sysParams["sign_method"] = $this->signMethod;

$sysParams["method"] = $request->getApiMethodName();

$sysParams["timestamp"] = date("Y-m-d H:i:s");

if (null != $session)

{

$sysParams["session"] = $session;

}

$apiParams = array();

//获取业务参数

$apiParams = $request->getApiParas();

//系统参数放入GET请求串

if($bestUrl){

$requestUrl = $bestUrl."?";

$sysParams["partner_id"] = $this->getClusterTag();

}else{

$requestUrl = $this->gatewayUrl."?";

$sysParams["partner_id"] = $this->sdkVersion;

}

//签名

$sysParams["sign"] = $this->generateSign(array_merge($apiParams, $sysParams));

foreach ($sysParams as $sysParamKey => $sysParamValue)

{

// if(strcmp($sysParamKey,"timestamp") != 0)

$requestUrl .= "$sysParamKey=" . urlencode($sysParamValue) . "&";

}

$fileFields = array();

foreach ($apiParams as $key => $value) {

if(is_array($value) && array_key_exists('type',$value) && array_key_exists('content',$value) ){

$value['name'] = $key;

$fileFields[$key] = $value;

unset($apiParams[$key]);

}

}

// $requestUrl .= "timestamp=" . urlencode($sysParams["timestamp"]) . "&";

$requestUrl = substr($requestUrl, 0, -1);

//发起HTTP请求

try

{

if(count($fileFields) > 0){

$resp = $this->curl_with_memory_file($requestUrl, $apiParams, $fileFields);

}else{

$resp = $this->curl($requestUrl, $apiParams);

}

}

catch (Exception $e)

{

$this->logCommunicationError($sysParams["method"],$requestUrl,"HTTP_ERROR_" . $e->getCode(),$e->getMessage());

$result->code = $e->getCode();

$result->msg = $e->getMessage();

return $result;

}

unset($apiParams);

unset($fileFields);

//解析TOP返回结果

$respWellFormed = false;

if ("json" == $this->format)

{

$respObject = json_decode($resp);

if (null !== $respObject)

{

$respWellFormed = true;

foreach ($respObject as $propKey => $propValue)

{

$respObject = $propValue;

}

}

}

else if("xml" == $this->format)

{

$respObject = @simplexml_load_string($resp);

if (false !== $respObject)

{

$respWellFormed = true;

}

}

//返回的HTTP文本不是标准JSON或者XML,记下错误日志

if (false === $respWellFormed)

{

$this->logCommunicationError($sysParams["method"],$requestUrl,"HTTP_RESPONSE_NOT_WELL_FORMED",$resp);

$result->code = 0;

$result->msg = "HTTP_RESPONSE_NOT_WELL_FORMED";

return $result;

}

//如果TOP返回了错误码,记录到业务错误日志中

if (isset($respObject->code))

{

$logger = new TopLogger;

$logger->conf["log_file"] = rtrim(TOP_SDK_WORK_DIR, '\\/') . '/' . "logs/top_biz_err_" . $this->appkey . "_" . date("Y-m-d") . ".log";

$logger->log(array(

date("Y-m-d H:i:s"),

$resp

));

}

return $respObject;

}

public function exec($paramsArray)

{

if (!isset($paramsArray["method"]))

{

trigger_error("No api name passed");

}

$inflector = new LtInflector;

$inflector->conf["separator"] = ".";

$requestClassName = ucfirst($inflector->camelize(substr($paramsArray["method"], 7))) . "Request";

if (!class_exists($requestClassName))

{

trigger_error("No such api: " . $paramsArray["method"]);

}

$session = isset($paramsArray["session"]) ? $paramsArray["session"] : null;

$req = new $requestClassName;

foreach($paramsArray as $paraKey => $paraValue)

{

$inflector->conf["separator"] = "_";

$setterMethodName = $inflector->camelize($paraKey);

$inflector->conf["separator"] = ".";

$setterMethodName = "set" . $inflector->camelize($setterMethodName);

if (method_exists($req, $setterMethodName))

{

$req->$setterMethodName($paraValue);

}

}

return $this->execute($req, $session);

}

private function getClusterTag()

{

return substr($this->sdkVersion,0,11)."-cluster".substr($this->sdkVersion,11);

}

}

一键复制

编辑

Web IDE

原始数据

按行查看

历史

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值