简体   繁体   中英

Why is my PHP cURL request to this API not pulling any data when the same request works in Postman?

EDIT: I have added a conditional statement to my code to check the result of curl_error($ch). It is apparently not returning an error. I have also added a curl_setop to set CURLOPT_POST to true.

I am trying to connect to an API using PHP and cURL and pull back a JSON response to be displayed on the page however while my initial request for an Access Token is successful with a simple GET request, I am not being returned any data by my subsequent POST requests.

I have been able to use Postman (screenshot below) to test the POST request and successfully receive a response, so the data I am sending in the POST request appears to be correct and the Access Token appears to work however when my PHP makes the request it appears that nothing is returned when I use json_decode and then print_r to display the contents of the JSON response.

I am very unfamiliar with cURL and so my code has been taken from a tutorial at this link: https://www.codexworld.com/post-receive-json-data-using-php-curl/ . The API documentation is provided at this link: NUACOM API - Reports

The following is my code:

$nuacom_get_api_key_url = "https://api.nuacom.ie/login_digest?email=abc@xyz.com&pass=123"; //dummy credentials for stackoverflow
$response_json = file_get_contents($nuacom_get_api_key_url);
$response_array = json_decode($response_json,true);
    
$session_token = $response_array['session_token'];

// API URL
$url = 'https://api.nuacom.ie/v1/reports/queue_inbound_stats';

// Create a new cURL resource
$ch = curl_init($url);

// Setup request to send json via POST
$data = array(
    "group_by" => "day",
    "time_from" => "2020-08-27 00:00:01",
    "time_to" => "2020-08-27 23:59:59",
    "queue" => "1",
    "client-security-token" => $session_token
);
            
$payload = json_encode($data);

// Set the request type to POST
curl_setopt($ch, CURLOPT_POST, 1);

// Attach encoded JSON string to the POST fields
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);

// Set the content type to application/json
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));

// Return response instead of outputting
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// Execute the POST request
$result = curl_exec($ch);

if(curl_exec($ch) === false)
{
    echo 'Curl error: ' . curl_error($ch);
}
else
{
    echo 'Operation completed without any errors'; //this is the line that is executed
}

// Close cURL resource
curl_close($ch);
            
$response_array = json_decode($result);

print_r($response_array);

Postman successful response:

邮差

Any help would be greatly appreciated! I'm sure it's something small that I am missing due to lack of familiarity with cURL and POST requests.

My bad. Maybe it's easier as an answer instead of comments so I can format the important parts.

You are creating an array with the data you want to send:

$data = array(
    "group_by" => "day",
    "time_from" => "2020-08-27 00:00:01",
    "time_to" => "2020-08-27 23:59:59",
    "queue" => "1",
    "client-security-token" => $session_token
);
  

and when you json_encode it to send it to the API you currently wrap it in another array

$payload = json_encode(array($data));

the result would be:

[{"group_by":"day","time_from":"2020-08-27 00:00:01","time_to":"2020-08-27 23:59:59","queue":"1","client-security-token":"token"}]

a json array. The api documentation for the "queue_inbound_stats" endpoint seems to ask for the data not being wrapped in another array like so

{"group_by":"day","time_from":"2020-08-27 00:00:01","time_to":"2020-08-27 23:59:59","queue":"1","client-security-token":"token"}

so just omit wrapping your $data array again:

$payload = json_encode($data);

in postman you're sending the data via the URL, and in curl you're sending the data in the request body json-encoded, the equivalent curl code to the postman would be:

$ch = curl_init();
curl_setopt_array($ch, array(
    CURLOPT_URL => 'https://api.nuacom.ie/v1/reports/queue_inbound_stats?' . http_build_query(array(
        "group_by" => "day",
        "time_from" => "2020-08-27 00:00:01",
        "time_to" => "2020-08-27 23:59:59",
        "queue" => "1",
        "client-security-token" => $session_token
    )),
    CURLOPT_POST => 1
));
curl_exec($ch);

... but reading the documentation at https://api.nuacom.ie/#operation/QueueReports , seems they want

$ch = curl_init();
curl_setopt_array($ch, array(
    CURLOPT_URL => 'https://api.nuacom.ie/v1/reports/queue_inbound_stats',
    CURLOPT_POST => 1,
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'client-security-token: '.$session_token,
    ),
    CURLOPT_POSTFIELDS => json_encode(array(
        "group_by" => "day",
        "time_from" => "2020-08-27 00:00:01",
        "time_to" => "2020-08-27 23:59:59",
        "queue" => "1",
    )),
    CURLOPT_POST => 1
));
curl_exec($ch);

hence it seems putting everything in the URL, as you're doing with Postman, is undefined/undocumented behavior, and it just happened to work anyway..

also the client-security-token does NOT go in the json, per the authentication documentation, it can go in the header, or in the url, but NOT in the json, your curl code is trying to put it in the JSON (while your Postman code put it in the url, together with everything else..)

If your postman request works fine, you can easily export your request to php/curl. This nice feature make your life easier. Just click on code button and you can export your request to curl, php/curl, C#, Go, and several other options.

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM