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?

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.