1

I am trying to make a PUT request, in order to edit some user's data, but I am receiving empty data instead of what I'm sending through my request.

I have tried with postman (a chrome plugin) and with a custom php snippet:

?php
$process = curl_init('http://localhost/myapp/api/users/1.json');

$headers = [
    'Content-Type:application/json',
    'Authorization: Basic "...=="'
];
$data = [
    'active' => 0,
    'end_date' => '01/01/2018'
];

curl_setopt($process, CURLOPT_HTTPHEADER, $headers);
curl_setopt($process, CURLOPT_TIMEOUT, 30);
curl_setopt($process, CURLOPT_PUT, 1);
curl_setopt($process, CURLOPT_POSTFIELDS, $data);
curl_setopt($process, CURLOPT_RETURNTRANSFER, TRUE);
$return = curl_exec($process);
curl_close($process);

print_r($return);

This is the code that I'm using cakephp-side:

class UsersController extends AppController
{
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('RequestHandler');
    }

    ....    

    public function edit($id = null)
    {
        debug($_SERVER['REQUEST_METHOD']);
        debug($this->request->data);
        die;
    }

    ....

And this is what it outputs:

/src/Controller/UsersController.php (line 318)
'PUT'


/src/Controller/UsersController.php (line 319)
[]

I am confused... similar code is working for a POST request and the add action... what is wrong with this code?

ToX 82
  • 1,064
  • 12
  • 35

1 Answers1

1

Two problems.

  1. When using CURLOPT_PUT, you must use CURLOPT_INFILE to define the data to send, ie your code currently doesn't send any data at all.

    CURLOPT_PUT

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

    http://php.net/manual/en/function.curl-setopt.php

  2. You are defining the data as an array.

    CURLOPT_POSTFIELDS

    [...] If value is an array, the Content-Type header will be set to multipart/form-data.

    http://php.net/manual/en/function.curl-setopt.php

    So even if the data would be sent, it would be sent as form data, which the request handler component wouldn't be able to decode (it would expect a JSON string), even if it would try to, which it won't, since your custom Content-Type header would not be set unless you'd pass the data as a string.

Long story short, use CURLOPT_CUSTOMREQUEST instead of CURLOPT_PUT, and set your data as a JSON string.

curl_setopt($process, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($process, CURLOPT_POSTFIELDS, json_encode($data));

Your Postman request likely has a similar problem.

ndm
  • 59,784
  • 9
  • 71
  • 110