【发布时间】:2016-10-02 09:16:02
【问题描述】:
您好,我是一名初级程序员,试图将 API 集成到我的移动应用程序中,这样我就可以从我的应用程序中查看来自亚马逊的商品。我已经完成了所有 6 个简单的步骤here,但该示例对我不起作用,如图所示here。
这是我的亚马逊 PHP 代码:
aws_signed_request.php
<?php
function aws_signed_request($region,$params,$public_key,$private_key,$associate_tag)
{
$method = "GET";
$host = "ecs.amazonaws.".$region; // must be in small case
$uri = "/onca/xml";
$params["Service"] = "AWSECommerceService";
$params["AWSAccessKeyId"] = $public_key;
$params["AssociateTag"] = $associate_tag;
$params["Timestamp"] = gmdate("Y-m-d\TH:i:s\Z");
$params["Version"] = "2009-03-31";
/* The params need to be sorted by the key, as Amazon does this at
their end and then generates the hash of the same. If the params
are not in order then the generated hash will be different thus
failing the authetication process.
*/
ksort($params);
$canonicalized_query = array();
foreach ($params as $param=>$value)
{
$param = str_replace("%7E", "~", rawurlencode($param));
$value = str_replace("%7E", "~", rawurlencode($value));
$canonicalized_query[] = $param."=".$value;
}
$canonicalized_query = implode("&", $canonicalized_query);
$string_to_sign = $method."\n".$host."\n".$uri."\n".$canonicalized_query;
/* calculate the signature using HMAC with SHA256 and base64-encoding.
The 'hash_hmac' function is only available from PHP 5 >= 5.1.2.
*/
$signature = base64_encode(hash_hmac("sha256", $string_to_sign, $private_key, True));
/* encode the signature for the request */
$signature = str_replace("%7E", "~", rawurlencode($signature));
/* create request */
$request = "http://".$host.$uri."?".$canonicalized_query."&Signature=".$signature;
/* I prefer using CURL */
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$xml_response = curl_exec($ch);
/* If cURL doesn't work for you, then use the 'file_get_contents'
function as given below.
*/
if ($xml_response === False)
{
return False;
}
else
{
/* parse XML */
$parsed_xml = @simplexml_load_string($xml_response);
return ($parsed_xml === False) ? False : $parsed_xml;
}
}
?>
amazon_api_class.php
<?php
require_once 'aws_signed_request.php';
class AmazonProductAPI
{
/**
* Your Amazon Access Key Id
* @access private
* @var string
*/
private $public_key = "AKIAJETPMOLIUXXXXXXX";
/**
* Your Amazon Secret Access Key
* @access private
* @var string
*/
private $private_key = "eHpNEaUwsf+HXXXXXXXXXXQGg7Ic2w+K5Gb6rYa";
/**
* Your Amazon Associate Tag
* Now required, effective from 25th Oct. 2011
* @access private
* @var string
*/
private $associate_tag = "mpXXXX-20";
/**
* Constants for product types
* @access public
* @var string
*/
/*
Only three categories are listed here.
More categories can be found here:
http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/APPNDX_SearchIndexValues.html
*/
const MUSIC = "Music";
const DVD = "DVD";
const GAMES = "VideoGames";
/**
* Check if the xml received from Amazon is valid
*
* @param mixed $response xml response to check
* @return bool false if the xml is invalid
* @return mixed the xml response if it is valid
* @return exception if we could not connect to Amazon
*/
private function verifyXmlResponse($response)
{
if ($response === False)
{
throw new Exception("Could not connect to Amazon");
}
else
{
if (isset($response->Items->Item->ItemAttributes->Title))
{
return ($response);
}
else
{
throw new Exception("Invalid xml response.");
}
}
}
/**
* Query Amazon with the issued parameters
*
* @param array $parameters parameters to query around
* @return simpleXmlObject xml query response
*/
private function queryAmazon($parameters)
{
return aws_signed_request("com", $parameters, $this->public_key, $this->private_key, $this->associate_tag);
}
/**
* Return details of products searched by various types
*
* @param string $search search term
* @param string $category search category
* @param string $searchType type of search
* @return mixed simpleXML object
*/
public function searchProducts($search, $category, $searchType = "UPC")
{
$allowedTypes = array("UPC", "TITLE", "ARTIST", "KEYWORD");
$allowedCategories = array("Music", "DVD", "VideoGames");
switch($searchType)
{
case "UPC" : $parameters = array("Operation" => "ItemLookup",
"ItemId" => $search,
"SearchIndex" => $category,
"IdType" => "UPC",
"ResponseGroup" => "Medium");
break;
case "TITLE" : $parameters = array("Operation" => "ItemSearch",
"Title" => $search,
"SearchIndex" => $category,
"ResponseGroup" => "Medium");
break;
}
$xml_response = $this->queryAmazon($parameters);
return $this->verifyXmlResponse($xml_response);
}
/**
* Return details of a product searched by UPC
*
* @param int $upc_code UPC code of the product to search
* @param string $product_type type of the product
* @return mixed simpleXML object
*/
public function getItemByUpc($upc_code, $product_type)
{
$parameters = array("Operation" => "ItemLookup",
"ItemId" => $upc_code,
"SearchIndex" => $product_type,
"IdType" => "UPC",
"ResponseGroup" => "Medium");
$xml_response = $this->queryAmazon($parameters);
return $this->verifyXmlResponse($xml_response);
}
/**
* Return details of a product searched by ASIN
*
* @param int $asin_code ASIN code of the product to search
* @return mixed simpleXML object
*/
public function getItemByAsin($asin_code)
{
$parameters = array("Operation" => "ItemLookup",
"ItemId" => $asin_code,
"ResponseGroup" => "Medium");
$xml_response = $this->queryAmazon($parameters);
return $this->verifyXmlResponse($xml_response);
}
/**
* Return details of a product searched by keyword
*
* @param string $keyword keyword to search
* @param string $product_type type of the product
* @return mixed simpleXML object
*/
public function getItemByKeyword($keyword, $product_type)
{
$parameters = array("Operation" => "ItemSearch",
"Keywords" => $keyword,
"SearchIndex" => $product_type);
$xml_response = $this->queryAmazon($parameters);
return $this->verifyXmlResponse($xml_response);
}
}
?>
Example.php
<?php
/* Example usage of the Amazon Product Advertising API */
include("amazon_api_class.php");
$obj = new AmazonProductAPI();
try
{
$result = $obj->searchProducts("X-Men Origins",
AmazonProductAPI::DVD,
"TITLE");
}
catch(Exception $e)
{
echo $e->getMessage();
}
print_r($result);
echo "Sales Rank : {$result->Items->Item->SalesRank}<br>";
echo "ASIN : {$result->Items->Item->ASIN}<br>";
echo "<br><img src=\"" . $result->Items->Item->MediumImage->URL . "\" /><br>";
?>
同样,这是运行Example.php的结果shown here.print_r($result);的结果是invalid xml respnse。
【问题讨论】:
-
首先,显而易见:“无效的 XML 响应”是由 您的代码 生成的文本,所以当测试
if (isset($response->Items->Item->ItemAttributes->Title))失败时,为什么不转储响应的内容,看看它是什么样的,而不是仅仅设置那个错误? -
嘿,谢谢您的浏览,您说得对。经过数周没有进展后,终于有了一些工作。谢谢!!
-
代码对我有用。它将所有结果打印为一个数组。 echo 语句有效,但它只显示第一个结果,因为它不是 foreach 循环。我目前不确定如何将其修改为 foreach 循环,尽管我正在研究它。如果您想一起解决此脚本,请与我联系。我打算在用户友好的设计中格式化所有结果
-
嘿@michaeld,我认为我对解决脚本没有多大帮助,但我真的不介意尝试!另外,在结果页面上,是否有任何 simpleXML 显示给你?就我而言,我的结果上方有一堆 simpleXML 代码。我目前遇到将 simpleXML 格式转换为 JSON 格式的问题。
标签: php xml api amazon-web-services