[9.x] Add ability to supply HTTP client methods with JsonSerializable instances#41055
[9.x] Add ability to supply HTTP client methods with JsonSerializable instances#41055taylorotwell merged 2 commits into
JsonSerializable instances#41055Conversation
JsonSerializable instancesJsonSerializable instances
|
Can you explain how your code change actually works and why it fixes the problem? |
|
The internal If we follow the code flow given my earlier 'after' example ( protected function parseRequestData($method, $url, array $options)
{
$laravelData = $options[$this->bodyFormat] ?? $options['query'] ?? []; // $laravelData is the User instance
$urlString = Str::of($url);
if (empty($laravelData) && $method === 'GET' && $urlString->contains('?')) { // $laravelData isn't empty, so remains the User instance
$laravelData = (string) $urlString->after('?');
}
if (is_string($laravelData)) { // $laravelData isn't a string, so remains the User instance
parse_str($laravelData, $parsedData);
$laravelData = is_array($parsedData) ? $parsedData : [];
}
// at this point, $laravelData still isn't an array and before my fix it was returned as if it was, resulting in the error
if (!is_array($laravelData)) { // $laravelData isn't an array, but we should return one and we can't reliably convert it to an array, so we return an empty array instead
$laravelData = [];
}
return $laravelData;
}One could say we can call |
|
I think you used the default User model. Eloquent models implement the |
|
Thanks |
protected function parseHttpOptions(array $options)
{
if (isset($options[$this->bodyFormat])) {
if ($this->bodyFormat === 'multipart') {
$options[$this->bodyFormat] = $this->parseMultipartBodyFormat($options[$this->bodyFormat]);
} elseif ($this->bodyFormat === 'body') {
$options[$this->bodyFormat] = $this->pendingBody;
}
if (is_array($options[$this->bodyFormat])) {
$options[$this->bodyFormat] = array_merge(
$options[$this->bodyFormat], $this->pendingFiles
);
}
} else {
$options[$this->bodyFormat] = $this->pendingBody;
}
if ($laravelData instanceof JsonSerializable) {
$laravelData = $laravelData->jsonSerialize();
}
return collect($options)->toArray();
}@taylorotwell Should add at this? |
|
@huangdijia if we use |



Problem
Guzzle supports "any PHP type that can be operated on by PHP's json_encode() function" as JSON body format, but the current implementation prevents using anything other than a string or an array (or
Arrayable). This is because the logic that parses the request data for assertions assumes it's always either of those types.Description
This PR introduces the ability – or fixes the bug, depends how you see it – to supply
JsonSerializableinstances into the Laravel HTTP Client for more convenient use.Usage
Before
After
This example uses a class that implements
JsonSerializable, but it can be anything thatjson_encodecan handle.