Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST request data can't be read in 'put' method

Tags:

json

rest

php

curl

api

I'm trying to develop a RESTful API with PHP without using frameworks. While processing the request, the client data cannot be read using this: parse_str(file_get_contents("php://input"), $put_vars);

Here's the full code:

public static function processRequest() {

    //get the verb
    $method = strtolower($_SERVER['REQUEST_METHOD']);

    $request = new Request();

    $data = array();
    $put_vars = array();

    switch ($method) {
        case 'get':
            $data = $_GET;
            break;
        case 'post':
            $data = $_POST;
            break;
        case 'put':
            parse_str(file_get_contents("php://input"), $put_vars);
            $data = $put_vars;
            echo $data;
            break;
    }

    $request->setMethod($method);
    $request->setRequestVars($data);

    if (isset($data['data'])) {
        $request->setData(json_decode($data));
        echo 'data exists';
    }

    return $request;
}

I'm using cURL to rest the API and when I type this command: curl -i -X PUT -d '{"name":"a","data":"data1"}' http://localhost/my-rest-api/api/ I only get this back:

Array""

Why isn't the proper data returned?

EDIT

I also tested another piece of code that is supposed to be an API and file_get_contents('php://input', true) still returns null. Could it be that there's something wrong with the web server?

like image 523
Igor Avatar asked Sep 30 '13 14:09

Igor


2 Answers

The parse_str is used to parse a query string(in form arg1=xyz&arg2=abc) and not JSON. You need to use json_decode to parse JSON strings.

$data = json_decode(file_get_contents("php://input"), true);

Here is the code that works:

$method = strtolower($_SERVER['REQUEST_METHOD']);
$data = array();

switch ($method) {
    case 'get':
        $data = $_GET;
        break;
    case 'post':
        $data = $_POST;
        break;
    case 'put':
        $data = json_decode(file_get_contents("php://input"), true);
        break;
}

var_dump($data);

Curl command:

curl -i -X PUT -d '{"name":"a","data":"data1"}' http://my-server/my.php

Response:

array(2) {
  ["name"]=>
  string(1) "a"
  ["data"]=>
  string(5) "data1"
}
like image 85
Shimon Rachlenko Avatar answered Sep 21 '22 19:09

Shimon Rachlenko


Could it be that there's something wrong with the web server?

Actually yes. After banging my head on this for a few hours, I found that the culprit for the missing data was this:

Note: Prior to PHP 5.6, a stream opened with php://input could only be read once

Another piece of code was accessing the php://input before my code, and on servers with php < 5.6, this caused the input to be lost.

Only on PUT requests that is.

like image 25
pkExec Avatar answered Sep 21 '22 19:09

pkExec