PHP对接Amazon Product Advertising API触发FATAL ERROR求助
PHP对接Amazon Product Advertising API非SDK实现触发Fatal Error排查
问题描述
近几日尝试使用PHP对接Amazon Product Advertising API,先后测试了SDK与非SDK两种对接方式均无法正常调用。运行非SDK实现代码时触发PHP FATAL ERROR,报错信息如下:
root@difmode:/var/www/html/cms# php index.php
PHP Fatal error: Uncaught Exception: Exception Occured in /var/www/html/cms/index.php:56
Stack trace:
#0 {main}
thrown in /var/www/html/cms/index.php on line 56
故障代码
<?php /** * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://www.apache.org/licenses/LICENSE-2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ include ("aws.php"); $searchItemRequest = new SearchItemsRequest (); $searchItemRequest->PartnerType = "Associates"; // Put your Partner tag (Store/Tracking id) in place of Partner tag $searchItemRequest->PartnerTag = "***"; $searchItemRequest->Keywords = "Harry"; $searchItemRequest->SearchIndex = "All"; $searchItemRequest->Resources = ["Images.Primary.Small","ItemInfo.Title","Offers.Listings.Price"]; $host = "webservices.amazon.com"; $path = "/paapi5/searchitems"; $payload = json_encode ($searchItemRequest); //Put your Access Key in place of <ACCESS_KEY> and Secret Key in place of <SECRET_KEY> in double quotes $awsv4 = new AwsV4 ("***", "***"); $awsv4->setRegionName("us-east-1"); $awsv4->setServiceName("ProductAdvertisingAPI"); $awsv4->setPath ($path); $awsv4->setPayload ($payload); $awsv4->setRequestMethod ("POST"); $awsv4->addHeader ('content-encoding', 'amz-1.0'); $awsv4->addHeader ('content-type', 'application/json; charset=utf-8'); $awsv4->addHeader ('host', $host); $awsv4->addHeader ('x-amz-target', 'com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems'); $headers = $awsv4->getHeaders (); $headerString = ""; foreach ( $headers as $key => $value ) { $headerString .= $key . ': ' . $value . "\r\n"; } $params = array ( 'http' => array ( 'header' => $headerString, 'method' => 'POST', 'content' => $payload ) ); $stream = stream_context_create ( $params ); $fp = @fopen ( 'https://'.$host.$path, 'rb', false, $stream ); if (! $fp) { throw new Exception ( "Exception Occured" ); } $response = @stream_get_contents ( $fp ); if ($response === false) { throw new Exception ( "Exception Occured" ); } echo $response; class SearchItemsRequest { public $PartnerType; public $PartnerTag; public $Keywords; public $SearchIndex; public $Resources; } ?>
故障排查&解决方案
你代码里用@符号压制了fopen和流读取的所有错误信息,导致看不到实际的请求失败原因,先把两处@删掉重新运行,就能拿到具体的接口返回错误。常见的触发56行报错的原因有以下几种:
- 配置参数错误:检查替换的Access Key、Secret Key、PartnerTag是否和亚马逊联盟后台的配置完全一致,不要多打空格或特殊字符
- 区域不匹配:如果你的亚马逊联盟账号对应区域不是美国站,需要把
$host和setRegionName的值改成对应区域的配置,比如日本站host要改成webservices.amazon.co.jp,region改成us-west-2 - 签名生成错误:检查
aws.php里的AwsV4类是否完整,签名算法是否符合PAAPI 5.0要求,常见错误是加密时漏加服务名、区域名参数 - 网络连通问题:检查运行代码的服务器是否能正常访问
webservices.amazon.com,可以直接在服务器上执行curl https://webservices.amazon.com/paapi5/searchitems测试连通性,国内服务器大概率会因为网络问题无法请求亚马逊接口 - PHP配置问题:检查php.ini是否开启了
allow_url_fopen,如果未开启fopen无法发起HTTP请求,改成开启状态或者用curl重写请求逻辑即可
内容的提问来源于stack exchange,提问作者iam_mine
相关产品推荐
相关产品推荐

