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.
$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:
$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.