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にあげると同じエラーがでるかなと思います。