phpを7.3からphp8.0にあげるためのスクリプト確認中に以下の事象が発生しました。
[事象]
paapi5-php-sdkを使ったスクリプトでAmazonのProduct Advertising APIから情報を取得しようとすると以下のエラーメッセージを出力してスクリプトが停止する。
Cannot change a fulfilled promise to rejected
[詳細]
paapi5-php-sdkのGetItems.phpのfunction getItemsAsync()において、$exceptionの詳細を確認するため以下のようにスクリプトを変更しました。
try {
$promise = $apiInstance->getItemsAsync($getItemsRequest);
$response = $promise->wait();
$promise->then(
function ($response) {
return $response;
},
function (\Exception $exception) {
return FALSE;
}
);
echo $response, PHP_EOL;
} catch (ApiException $exception) {
return FALSE;
} catch (Exception $exception) {
var_dump($exception); → 追加
return FALSE;
}
$exceptionの内容は以下のとおりでした。
object(LogicException)#20 (7) {
["message":protected]=>
string(45) "Cannot change a fulfilled promise to rejected"
["string":"Exception":private]=>
string(0) ""
["code":protected]=>
int(0)
["file":protected]=>
string(72) "/paapi5-php-sdk/vendor/guzzlehttp/promises/src/Promise.php"
["line":protected]=>
int(130)
["trace":"Exception":private]=>
array(13) {
[0]=>
array(6) {
["file"]=>
string(72) "/paapi5-php-sdk/vendor/guzzlehttp/promises/src/Promise.php"
["line"]=>
int(118)
["function"]=>
string(6) "settle"
["class"]=>
string(26) "GuzzleHttp\Promise\Promise"
["type"]=>
string(2) "->"
["args"]=>
array(2) {
[0]=>
string(8) "rejected"
[1]=>
object(TypeError)#98 (7) {
["message":protected]=>
string(90) "method_exists(): Argument #1 ($object_or_class) must be of type object|string, array given"
["string":"Error":private]=>
string(0) ""
["code":protected]=>
int(0)
["file":protected]=>
string(72) "/paapi5-php-sdk/vendor/guzzlehttp/promises/src/Promise.php"
["line":protected]=>
int(151)
Promise.phpの151行目は以下のとおりでした。
if (!method_exists($value, 'then')) {
PHP8かPHP7.4で、method_existsの第一引数にobject/string以外の型を渡すとerrorになるように変更されたのかな…
if (!method_exists((object)$value, 'then')) {
と書くと動くことを確認しました。
おそらく最新のguzzlehttpなら動くと思い、guzzlehttpを最新のリビジョン(6.5.5)にあげたところ動作しました。
該当部分は
if (!is_object($value) || !method_exists($value, 'then')) {
と修正されていました。自分がpaapi5-php-sdkを使い始めたのはProduct Advertising API 5の導入時期でした。
今のpaapi5-php-sdkを確認したところ、同梱されているguzzlehttpは6.5.3でしたので問題ないです。
自分と同じようにpaapi5-php-sdkを初期に導入して何もしていない…場合は、PHPを7.3から8.0にあげると同じエラーがでるかなと思います。