I just lost an hour or 2 of my life to this, so I figure I’ll do a small write-up to save future me from having to do the same dance.
I had the following piece of code, that wasn’t doing what I expected.
<?php
$client = new Client([
'http_errors' => false,
'verify' => false,
'headers' => [
'Content-Type' => 'application/json',
],
]);
try {
$response = $client->post('/', [
'form_params' => '{"query":"{some_json}"}',
]);
} catch (GuzzleException $exception) {
// ...
}
Whenever the Guzzle call would execute, it would overwrite my provided Content-Type
header with the application/x-www-form-urlencoded
value.
What I’m trying to do looks weird, but is intentional: I want to send a JSON payload, but send it as if it was a simple form submission. I don’t want to use Guzzle’s json method for this.
This should work, because the docs say:
[form_params] Sets the Content-Type header to application/x-www-form-urlencoded when no Content-Type header is already present.
But my header was already present, yet Guzzle overwrites it!
Turns out, I was applying that header in the wrong place. Silly me. The headers
array should be moved directly to the $client->post()
call, not set as the defaults of the client.
My fix was to just move them:
<?php
$client = new Client([
'http_errors' => false,
'verify' => false,
]);
try {
$response = $client->post('/', [
'headers' => [
'Content-Type' => 'application/json',
],
'form_params' => '{"query":"{some_json}"}',
]);
} catch (GuzzleException $exception) {
// ...
}
Remove them from the Client()
instantiation and set the headers directly to the HTTP call that is being executed.
Lesson learned: the docs might be right, but they aren’t very clear.