I'm trying to post data to an API using PHP curl. When I manually paste the json_encoded output into the code it works fine but when I assign through a variable I get an error 400 Bad Syntax from the API.
I've tried manipulating the variable to ensure it is identical to a known working string but the printed output in the error log shows me that the escaping backslashes remain.
//Get the data
$sql = "SELECT name, date, amount FROM table";
$result = mysqli_query($conn, $sql);
//Convert the output to JSON format
$rows = array();
while($r = mysqli_fetch_assoc($result)) {
$rows[] = $r;
}
$encodedJSON = json_encode($rows, JSON_NUMERIC_CHECK);
if (mysqli_num_rows($result) == 1) {
$encodedJSON = '{ "single": ' . $encodedJSON . ' }';
} else {
$encodedJSON = '{ "multiple": ' . $encodedJSON . ' }';
}
$access_token = 'Bearer ' . $access_token;
$encodedJSON = addslashes($encodedJSON);
error_log($encodedJSON);
//Start Curl
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => $encodedJSON,
CURLOPT_HTTPHEADER => array(
"Accept-Encoding: gzip, deflate",
"Authorization: " . $access_token,
"Cache-Control: no-cache",
"Connection: keep-alive",
"Content-Length: 354",
"Content-Type: application/json",
"accept: application/json",
"cache-control: no-cache"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
}
I suspect a backslash issue is at play here but I can't resolve it.
$encodedJSON is outputting to error_log. When I check the error_log file I can see that the string is outputting like this:
"{ \"multiple\": [{\"name\":\"Joe Bloggs\",\"date\":\"2019-08-06\",\"amount\":34},{\"name\":\"Bloggy Joe\",\"date\":\"2019-08-07\",\"amount\":237}] }"
The strange thing is, if I copy/paste this exact string and hardcode it into a new variable - let's say $HARDencodedJSON
:
$HARDencodedJSON = "{ \"multiple\": [{\"name\":\"Joe Bloggs\",\"date\":\"2019-08-06\",\"amount\":34},{\"name\":\"Bloggy Joe\",\"date\":\"2019-08-07\",\"amount\":237}] }";
Then it outputs to the error log like this:
{ "multiple": [{"name":"Joe Bloggs","date":"2019-08-06","amount":34},{"name":"Bloggy Joe","date":"2019-08-07","amount":237}] }
In other words, the backslashes get stripped out of the hardcoded variable but they remain in the original one.
Likewise, if I were to swap out CURLOPT_POSTFIELDS => $encodedJSON
, for CURLOPT_POSTFIELDS => $HARDencodedJSON
, the whole thing works perfectly.
UPDATED: I'm still stumped here is anyone can help please?
With the following code in place I'm getting what looks like perfectly formed output in my error_log but the cURL is timing out:
$encodedJSON = json_encode(array("multiple"=>$rows),JSON_NUMERIC_CHECK);
I've removed addslashes so there's no further string manipulation.
Then I simply add the variable to my cURL setup as follows:
CURLOPT_POSTFIELDS => $encodedJSON,
The response is a cURL timeout as follows: cURL Error #:Operation timed out after 30000 milliseconds with 0 bytes received
If I addslashes back in, cURL does not timeout anymore and the API endpoint responds with an error 400 Bad Request.
Is there any way I can see the exact cURL command being sent over? I've tried a verbose debug but it doesn't show exactly what CURLOPT_POSTFIELDS is set to?