skip to Main Content

I need to PUT some json data to an API endpoint, which works as expected via command line curl, but not via php curl and I don’t have any idea, why it doesn’t.

my command is

curl -v --insecure --request PUT --url <https://blabla/blablabla> --user 'username:password' --header 'Content-Type: application/json' --data '<valid json data>'

but it doesn’t work this way within php:

  // get cURL resource
  $curl = curl_init();
  
  // set cURL options
  $curloptions = array(
    CURLOPT_PUT => true,                // set method to PUT
    CURLOPT_RETURNTRANSFER => true,         // return the transfer as a string
    CURLOPT_VERBOSE => true,                // output verbose information
    CURLOPT_SSL_VERIFYHOST => false,            // ignore self signed certificates
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_USERNAME => $config['uag']['user'],     // set username
    CURLOPT_PASSWORD => $config['uag']['pass'],     // set password
    CURLOPT_HTTPHEADER => array(            // set headers
      "Content-Type: application/json",
    ),
    CURLOPT_POSTFIELDS => $jsondata         // set data to post / put
    );
  curl_setopt_array($curl, $curloptions);

  foreach($serverurilist as $uri) {
    // set url
    curl_setopt($curl, CURLOPT_URL, $uri);
    // send the request and save response to $response
    $response = curl_exec($curl);

    // stop if fails
    if(!$response) {
      die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
    }
    var_dump($response);
  }

  // close curl resource to free up system resources
  curl_close($curl);

What doesn’t work? The payload / data doesn’t get submitted. If I tcpdump the command line und php version without encryption, I can see, that the command line submits the data right after the Expect: 100-continue request and the HTTP/1.1 100 Continue response from the server. The php version doesn’t do anything after the HTTP/1.1 100 Continue response and quits after reaching the timeout.

2

Answers


  1. From documentation:

    CURLOPT_PUTtrue to HTTP PUT a file. The file to PUT must be set with CURLOPT_INFILE and CURLOPT_INFILESIZE.

    and you are not using any file to provide content.

    You should use CURLOPT_CUSTOMREQUEST => 'PUT'.


    This is your same cUrl request exported from Postman:

    
    $curl = curl_init();
    
    curl_setopt_array($curl, array(
      CURLOPT_URL => 'https://blabla/blablabla',
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_ENCODING => '',
      CURLOPT_MAXREDIRS => 10,
      CURLOPT_TIMEOUT => 0,
      CURLOPT_FOLLOWLOCATION => true,
      CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
      CURLOPT_CUSTOMREQUEST => 'PUT',
      CURLOPT_POSTFIELDS =>'<valid json data>',
      CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ='
      ],
    ));
    
    $response = curl_exec($curl);
    
    curl_close($curl);
    echo $response;
    
    
    Login or Signup to reply.
  2. You should use this CURLOPT_CUSTOMREQUEST=>'PUT'

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search