第八天
话说小帅帅自从走进了淘宝开放平台这个迷雾森林,感觉这迷雾森林好大,正当他无所适从的时候。
一位悦耳动听的声音响起来了,甜甜的声音说道:亲,想通过这片森林吗,我将指引你前进。
小帅帅一听,那种感觉,身体不由自主的跟随这声音而去,突然一道强光闪过,啊.....
小帅帅惊醒了。小帅帅一看时间,我滴个天,这么晚了。就这样小帅帅从业一来第一次迟到。
其实小帅帅在平台里面琢磨了一个晚上,整个晚上其实也没琢磨个啥出来。
正当要到公司的时候,手机的铃声响起来了,一看是于老大的电话,接通电话。
于老大问候到:小帅帅,早啊, 你什么时候到公司丫。
小帅帅答到: 于老大,不好意思丫,昨天晚上研究那个淘宝开放平台,研究太玩了,今早睡过头了。不过我快到公司了....
于老大一听,不好意思责怪小帅帅啥,只好说道:辛苦你了,注意休息,学会劳逸结合...
小帅帅,回到: 好的,谢谢于老大的教诲,没事就挂了哈。。( 0害怕于老大的糖衣炮弹0 )
小帅帅回到公司后,于老大就给了一份整理后的Topclient给小帅帅,让他去研究下,看样子小帅帅还是乐于研究代码,让他看开放平台,还真看不出什么。
淘宝宝贝API文档:http://open.taobao.com/api/api_cat_detail.htm?spm=a219a.7386789.0.0.AjaroV&cat_id=4&category_id=102
Topclient来自Taobao SDK ,只是稍微修正,去掉了一些框架的依赖,源码为:
<?php class TopClient { public $appkey; public $secretKey; public $gatewayUrl = "http://gw.api.taobao.com/router/rest"; public $format = "json"; /** 是否打开入参check**/ public $checkRequest = true; protected $signMethod = "md5"; protected $apiVersion = "2.0"; protected $sdkVersion = "top-sdk-php-20110929"; protected function generateSign($params) { ksort($params); $stringToBeSigned = $this->secretKey; foreach ($params as $k => $v) { if ("@" != substr($v, 0, 1)) { $stringToBeSigned .= "$k$v"; } } unset($k, $v); $stringToBeSigned .= $this->secretKey; return strtoupper(md5($stringToBeSigned)); } protected 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); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); curl_setopt($ch, CURLOPT_TIMEOUT, 300); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); if (is_array($postFields) && 0 < count($postFields)) { $postBodyString = ""; $postMultipart = false; foreach ($postFields as $k => $v) { if ("@" != substr($v, 0, 1)) //判断是不是文件上传 { $postBodyString .= "$k=" . urlencode($v) . "&"; } else //文件上传用multipart/form-data,否则用www-form-urlencoded { $postMultipart = true; } } unset($k, $v); curl_setopt($ch, CURLOPT_POST, true); if ($postMultipart) { curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); } else { 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; } protected function logCommunicationError($apiName, $requestUrl, $errorCode, $responseTxt) { $localIp = isset($_SERVER["SERVER_ADDR"]) ? $_SERVER["SERVER_ADDR"] : "CLI"; $logData = "NAME:$apiName,KEY:$this->appkey,IP:$localIp,URL:$requestUrl,CODE:$errorCode,MSG:" . str_replace("\n", "", $responseTxt); $file = fopen('taobao.api.error.log','a+'); fwrite($file,$logData); fclose($file); } public function execute($request, $session = null, $need_replace = false) { if ($this->checkRequest) { try { $request->check(); } catch (Exception $e) { $result = new stdClass(); $result->code = $e->getCode(); $result->msg = $e->getMessage(); return $result; } } //组装系统参数 $sysParams["v"] = $this->apiVersion; $sysParams["format"] = $this->format; $sysParams["method"] = $request->getApiMethodName(); $sysParams["app_key"] = $this->appkey; $sysParams["timestamp"] = date("Y-m-d H:i:s"); $sysParams["partner_id"] = $this->sdkVersion; $sysParams["sign_method"] = $this->signMethod; if (null != $session) { $sysParams["session"] = $session; } //获取业务参数 $apiParams = $request->getApiParas(); //签名 $sysParams["sign"] = $this->generateSign(array_merge($apiParams, $sysParams)); //系统参数放入GET请求串 $requestUrl = $this->gatewayUrl . "?"; foreach ($sysParams as $sysParamKey => $sysParamValue) { $requestUrl .= "$sysParamKey=" . urlencode($sysParamValue) . "&"; } $requestUrl = substr($requestUrl, 0, -1); //发起HTTP请求 try { $resp = $this->curl($requestUrl, $apiParams); } catch (Exception $e) { $this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_ERROR_" . $e->getCode(), 'RETRY:' . $e->getMessage()); $result = new stdClass(); $result->code = $e->getCode(); $result->msg = $e->getMessage(); return $result; } //解析TOP返回结果 $respWellFormed = false; if ("json" == $this->format) { if ($need_replace) { $resp = preg_replace('/[\r\n]+/', '', $resp); } $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 = new stdClass(); $result->code = 0; $result->msg = "HTTP_RESPONSE_NOT_WELL_FORMED"; return $result; } return $respObject; } }
淘宝宝贝请求类:
<?php /** * TOP API: taobao.item.get request * * @author auto create * @since 1.0, 2011-09-29 15:36:21 */ class ItemGetRequest { /** * 需要返回的商品对象字段。可选值:Item商品结构体中所有字段均可返回;多个字段用“,”分隔。如果想返回整个子对象,那字段为item_img,如果是想返回子对象里面的字段,那字段为item_img.url。新增返回字段:second_kill(是否秒杀商品)、auto_fill(代充商品类型),props_name(商品属性名称) **/ private $fields; /** * 商品数字ID **/ private $numIid; private $apiParas = array(); public function setFields($fields) { $this->fields = $fields; $this->apiParas["fields"] = $fields; } public function getFields() { return $this->fields; } public function setNumIid($numIid) { $this->numIid = $numIid; $this->apiParas["num_iid"] = $numIid; } public function getNumIid() { return $this->numIid; } public function getApiMethodName() { return "taobao.item.get"; } public function getApiParas() { return $this->apiParas; } public function check() { RequestCheckUtil::checkNotNull($this->fields, "fields"); RequestCheckUtil::checkNotNull($this->numIid, "numIid"); RequestCheckUtil::checkMinValue($this->numIid, 1, "numIid"); } }
数据完整性检测类
<?php /** * API入参静态检查类 * 可以对API的参数类型、长度、最大值等进行校验 * **/ class RequestCheckUtil { /** * 校验字段 fieldName 的值$value非空 * **/ public static function checkNotNull($value,$fieldName) { if(self::checkEmpty($value)){ throw new Exception("client-check-error:Missing Required Arguments: " .$fieldName , 40); } } /** * 检验字段fieldName的值value 的长度 * **/ public static function checkMaxLength($value,$maxLength,$fieldName){ if(!self::checkEmpty($value) && strlen($value) > $maxLength){ throw new Exception("client-check-error:Invalid Arguments:the length of " .$fieldName . " can not be larger than " . $maxLength . "." , 41); } } /** * 检验字段fieldName的值value的最大列表长度 * **/ public static function checkMaxListSize($value,$maxSize,$fieldName) { if(self::checkEmpty($value)) return ; $list=split(",",$value); if(count($list) > $maxSize){ throw new Exception("client-check-error:Invalid Arguments:the listsize(the string split by \",\") of ". $fieldName . " must be less than " . $maxSize . " ." , 41); } } /** * 检验字段fieldName的值value 的最大值 * **/ public static function checkMaxValue($value,$maxValue,$fieldName){ if(self::checkEmpty($value)) return ; self::checkNumeric($value,$fieldName); if($value > $maxValue){ throw new Exception("client-check-error:Invalid Arguments:the value of " . $fieldName . " can not be larger than " . $maxValue ." ." , 41); } } /** * 检验字段fieldName的值value 的最小值 * **/ public static function checkMinValue($value,$minValue,$fieldName) { if(self::checkEmpty($value)) return ; self::checkNumeric($value,$fieldName); if($value < $minValue){ throw new Exception("client-check-error:Invalid Arguments:the value of " . $fieldName . " can not be less than " . $minValue . " ." , 41); } } /** * 检验字段fieldName的值value是否是number * **/ protected static function checkNumeric($value,$fieldName) { if(!is_numeric($value)) throw new Exception("client-check-error:Invalid Arguments:the value of " . $fieldName . " is not number : " . $value . " ." , 41); } /** * 校验$value是否非空 * if not set ,return true; * if is null , return true; * * **/ public static function checkEmpty($value) { if(!isset($value)) return true ; if($value === null ) return true; if(trim($value) === "") return true; return false; } }
来自Taobao SDK,非原创。稍微修订。
小帅帅拿着一看,又是天书,悲剧了。。 继续研究吧。。
就这样小帅帅又躲深山去修炼九阴真经了。