使用Guzzle PHP库Pool发送请求时西里尔字符处理异常如何解决?
It sounds like the problem stems from how you're constructing request URLs when using Guzzle Pool. When you manually concatenate the text parameter into the URL (like 'https://api_endpoint/?text=' . $text), you’re relying on accidental encoding or environment-specific behavior that doesn’t hold up in batch mode. Here’s how to fix it properly:
The Root Cause
Guzzle doesn’t automatically re-encode query parameters hardcoded into URL strings. For Cyrillic characters (or any non-ASCII text), you need proper URL encoding per RFC 3986 to ensure the API can parse the parameter correctly. Your individual requests might have worked due to luck (maybe your $text was already encoded elsewhere), but batch requests expose the missing encoding step.
The Solution: Let Guzzle Handle Query Parameter Encoding
Instead of manually building URLs with concatenated parameters, use Guzzle’s built-in query option to pass parameters as an array. Guzzle will automatically encode all characters (including Cyrillic) correctly—whether you’re sending a single request or using Pool.
Step 1: Update Individual Requests (for consistency)
Even though your single requests worked, switch to this pattern to avoid future issues:
$response = $client->request('GET', 'https://api_endpoint/', [ 'query' => [ 'text' => $text ] ]);
Step 2: Build Batch Requests Correctly
When creating your $requests array for Pool, use the same query option instead of concatenating URLs:
Using Guzzle’s Request Class:
use GuzzleHttp\Psr7\Request; $requests = []; // Assume $texts is your array of texts (including Cyrillic ones) foreach ($texts as $text) { $requests[] = new Request( 'GET', 'https://api_endpoint/', [], null, [ 'query' => ['text' => $text] ] ); } // Execute batch requests $responses = Pool::batch($client, $requests, [ 'concurrency' => 15, ]);
Alternatively, Using Array-Based Requests:
If you prefer array syntax for requests, this works too:
$requests = array_map(function($text) { return [ 'method' => 'GET', 'uri' => 'https://api_endpoint/', 'query' => ['text' => $text] ]; }, $texts); $responses = Pool::batch($client, $requests, [ 'concurrency' => 15, ]);
Why This Works
Guzzle will automatically encode the text parameter value into the proper URL-encoded format. For example, the Cyrillic string Привет will be converted to %D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82, which the API can parse correctly without returning a "bad request" error.
Verify the Encoding
To confirm the fix, you can inspect the full request URL before sending. For a single request, run:
$request = $client->createRequest('GET', 'https://api_endpoint/', ['query' => ['text' => 'Привет']]); echo $request->getUri(); // Outputs: https://api_endpoint/?text=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82
This ensures your parameters are always encoded correctly, regardless of the character set or whether you’re sending requests individually or in batches.
内容的提问来源于stack exchange,提问作者roman_ds

