You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yii2中如何从异步GuzzleHttp请求返回响应及处理异常?

Fixing GuzzleHttp Async Request Response Handling & Promise Issues

Looks like you've hit two key issues with your Guzzle async implementation—let's break them down and fix this step by step.

First: Why you're getting a Response object instead of your array

When you call $promise->then(), it returns a new Promise that wraps your transformed response/error array. But you're not assigning this new Promise back to $promise, so when you call $promise->wait(), you're still waiting on the original Promise that resolves to the raw Response object. That's exactly why you're seeing the "Cannot use object of type GuzzleHttp\Psr7\Response as array" error.

Second: Unhandled edge case in error handling

If the request fails entirely (e.g., no connection, DNS failure), $e->getResponse() will return null. Trying to call getStatusCode() on that will throw another fatal error—we need to handle this scenario gracefully.

Third: A small variable typo in sendAsyncRequest

You're using $client->utm_source to build $url_params, but $client isn't a parameter of this method. You should be using the $params['utm_source'] that's passed into the method instead.


Here's the fixed version of your Logger class with all these issues addressed:

use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Exception\RequestException;
use Psr\Http\Message\ResponseInterface;

class Logger {
    public function processAsyncRequest($client) {
        $response = $this->sendAsyncRequest($client->phone, ['utm_source' => $client->utm_source]);
        $this->logResponse($client, $response);
    }

    public function sendAsyncRequest($phone, $params) {
        // Fix the variable typo here to use the passed-in params
        $url_params = http_build_query(['utm_source' => $params['utm_source']]);
        $guzzleClient = new GuzzleClient();
        $headers = [
            'Content-Type' => 'application/json',
            'Authorization' => 'Basic xxxxxxxxxx',
        ];
        $request = new Request('POST', 'url' . $phone . '/tokens/?' . $url_params, $headers);
        
        $promise = $guzzleClient->sendAsync($request);
        
        // Assign the transformed Promise back to $promise
        $promise = $promise->then(
            function (ResponseInterface $response) {
                return [
                    'code' => $response->getStatusCode(),
                    'body' => $response->getBody()->__toString(),
                ];
            },
            function(RequestException $e) {
                // Handle cases where no response was received at all
                $statusCode = $e->getResponse() ? $e->getResponse()->getStatusCode() : 0;
                $body = $e->getResponse() ? $e->getResponse()->getBody()->__toString() : $e->getMessage();
                
                return [
                    'code' => $statusCode,
                    'body' => $body,
                ];
            }
        );
        
        // Now wait() will resolve to our custom array instead of the raw Response
        $res = $promise->wait();
        return $res;
    }

    public function logResponse($client, $data) {
        $log = new Log();
        $log->client_id = $client->id;
        // Optional: Log the full actual URL for debugging purposes
        $log->url = 'url' . $client->phone . '/tokens/?' . http_build_query(['utm_source' => $client->utm_source]);
        $log->response = $data['code'] . ', ' . $data['body'];
        $log->comment = 'reg';
        return $log->save();
    }
}

Key Fixes Explained

  • Promise Chaining: By assigning $promise = $promise->then(...), we ensure that wait() resolves to our transformed array instead of the raw Response object.
  • Safe Error Handling: We added a check for $e->getResponse() before accessing its methods, preventing fatal errors when the request can't reach the server.
  • Variable Typo Fix: Swapped $client->utm_source for $params['utm_source'] to match the method's input parameters.
  • Optional Full URL Logging: Updated logResponse to log the complete URL used (you can remove this if not needed, but it's useful for debugging failed requests).

内容的提问来源于stack exchange,提问作者Dmitry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 18:07:36