-
Notifications
You must be signed in to change notification settings - Fork 11.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[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
#41055
Conversation
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
JsonSerializable
instances 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_encode
can handle.