Calaf Calaf - 20 days ago 5
JSON Question

Distinction between json decoding and objects in php

If I send the message

curl -i -H "Content-Type: application/json" -X POST \
-d '{"name": "Bob", "age": 32}' \
http://localhost:8000/user.php


while running
php -S localhost:8000
on the directory containing
user.php
:

<?php
class User {
public $name, $age;
function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
}

$user1 = json_decode(file_get_contents('php://input'), true);
$user2 = new User("Bob", 32);
?>


Is there any distinction between $user1 and $user2? If yes, how can I decode the message directly into an instance of class User? If no, does this mean that class User is altogether redundant in the sample above?

Docs:


Answer

First off, to get an object out of json_decode, you need to pass false as the second argument, otherwise the result (what you're currently getting) is an associative array. Note false is the default for the second argument, so you can simply omit it here.

Assuming you don't pass true for the second argument to json_decode, $user1 in your example is an instance of stdClass, whereas $user2 is an instance of User, so the instances are of different classes.

If you want to make the input into a User instance you could do

$rawUser = json_decode(file_get_contents('php://input'));
$user1   = new User($rawUser->name, $rawUser->age);

Another way might be a static factory method

class User {
    public $name, $age;
    function __construct($name, $age) {
        $this->name = $name;
        $this->age = $age;
    }

   static public function fromRaw(stdClass $rawUser) {
       $newUser = new self();
       $newUser->name = $rawUser->name;
       $newUser->age  = $rawUser->age;

       return $newUser;
   }
}

then you could revise the first example to

$rawUser = json_decode(file_get_contents('php://input'));
$user1   = User::fromRaw($rawUser);