0

I got an object. I need to turn into JSON for storage but when I try to encode it into JSON it returns an empty JSON object. When I tried to use json_last_error.

The code I used

echo $payload["sub"];
echo json_encode($user);
echo json_last_error_msg();

The result I get

"102573480781696194937{}No error".

The User class I'm trying to encode

<?php
    /**
     * Created by PhpStorm.
     * User: Student
     * Date: 13-4-2018
     * Time: 10:40
     */

    namespace php;
    class User
    {
        private $isAdmin = false;
        private $registeredFood = array();
        private $googleID;
        private $name;
        private $notes = array();
        private $email;

        /**
         * User constructor.
         * @param $googleID
         */
        public function __construct($googleID)
        {
            $this->googleID = $googleID;

        }


        /**
         * @return mixed
         */
        public function getGoogleID()
        {
            return $this->googleID;
        }

        /**
         * @return bool
         */
        public function isAdmin()
        {
            return $this->isAdmin;
        }

        /**
         * @param bool $isAdmin
         */
        public function setIsAdmin($isAdmin)
        {
            $this->isAdmin = $isAdmin;
        }

        /**
         * @return array
         */
        public function getRegisteredFood()
        {
            return $this->registeredFood;
        }

        /**
         * @param array $registeredFood
         */
        public function setRegisteredFood($registeredFood)
        {
            $this->registeredFood = $registeredFood;
        }

        /**
         * @return mixed
         */
        public function getName()
        {
            return $this->name;
        }

        /**
         * @param mixed $name
         */
        public function setName($name)
        {
            $this->name = $name;
        }

        /**
         * @return array
         */
        public function getNotes()
        {
            return $this->notes;
        }

        /**
         * @param array $notes
         */
        public function setNotes($notes)
        {
            $this->notes = $notes;
        }

        /**
         * @return mixed
         */
        public function getEmail()
        {
            return $this->email;
        }

        /**
         * @param mixed $email
         */
        public function setEmail($email)
        {
            $this->email = $email;
        }
    }
?>

I hope someone can help me

GYaN
  • 2,327
  • 4
  • 19
  • 39
Lars Dormans
  • 171
  • 1
  • 13
  • JSON is meant for encoding data and will not work on classes or bits of code. I am not sure what contents you have in variable `$user`. – Carsten Massmann Apr 18 '18 at 07:30
  • 3
    What do you expect it to encode? All properties are private. – M. Eriksson Apr 18 '18 at 07:30
  • @cars10m I got a User object stored in there – Lars Dormans Apr 18 '18 at 07:31
  • https://stackoverflow.com/questions/9896254/php-class-instance-to-json – deEr. Apr 18 '18 at 07:31
  • 2
    I would recommend you to look at PHP's [JsonSerializable](http://php.net/manual/en/class.jsonserializable.php) interface if you want complete control over the encoded json object. – M. Eriksson Apr 18 '18 at 07:32
  • Agreed @NigelRen approving duplicate designation – Lars Dormans Apr 18 '18 at 07:37
  • _Side note:_ This is just my opinion, but using "private" is rarely needed. (Not saying that it _never_ has a usage.) Using "protected" is, more often than not, a better approach since you then can access properties and functions more freely if you extend the class. – M. Eriksson Apr 18 '18 at 07:42

2 Answers2

4

It is because your class's properties are private.

An example class with only private properties ...

php > class Foo { private $bar = 42; }
php > $obj = new Foo();

do not expose values:

php > echo json_encode($obj);
{}

But an example class with public properties ...

php > class Bar { public $foo = 42; }
php > $objBar = new Bar();

do it!

php > echo json_encode($objBar);
{"foo":42}

\JsonSerializable

PHP provide an'interafce \JsonSerializable that require a method jsonSerialize. This method is automatically called by json_encode().

class JsonClass implements JsonSerialize {
    private $bar;
    public function __construct($bar) {
        $this->bar = $bar;
    }
    public function jsonSerialize() {
        return [
            'foo' => $this->bar,
        ];
    }
}

I prefer this solution because is not good to expose publicly properties

serialization and unserialization ...

If you need to serialize and unserialize php object you can ...

php > class Classe { public $pub = "bar"; }
php > $obj = new Classe();
php > $serialized = serialize($obj);
php > $original = unserialize($serialized);
php > var_dump($original);
php shell code:1:
class Classe#2 (1) {
  public $pub =>
  string(3) "bar"
}

$serialized variable contains O:6:"Classe":1:{s:3:"pub";s:3:"bar";}. As you can see is not a json, but is a format that allow you to recreate original object using unserialize function.

sensorario
  • 20,262
  • 30
  • 97
  • 159
  • 2
    Gah! I was just about to post an answer using the JsonSerializable interface. You beat me to the punch :-p I totally agree though. JsonSerializable is the cleanest approach. – M. Eriksson Apr 18 '18 at 07:38
  • Is there a JsonDeserializable interface to revert the encoding back to object? – Lars Dormans Apr 18 '18 at 07:41
  • @LarsDormans - No. When it's converted to JSON, it's simply a JSON object. JSON is a simple notation for presenting data, it doesn't have any concept of functions or similar. It's no longer your class. – M. Eriksson Apr 18 '18 at 07:44
  • No, but you can `$serialized = serialize($obj)` and unserialize with `$original = unserialize($serialized)`. An object serialized is quite different from json but it allow you to send objects via http requests ^_^ – sensorario Apr 18 '18 at 07:45
  • 1
    Just a heads up on `serialize()`. That creates a serialized version of your class, but it isn't a "general" notation. It's PHP-specific, so if you want to be able to use that data in some other language, you would need to create a parser for it yourself. – M. Eriksson Apr 18 '18 at 07:48
  • @LarsDormans I've edited the answer about serialization and unserialization of php objects. – sensorario Apr 18 '18 at 07:52
0

You have a couple of options here.

Option 1: Make your class properties public

Like what sensorario mentioned, change the visibility of your properties so that it is accessible from outside the class, which is where you are calling json_encode.

Option 2: Introduce a method/function within the class to return the encoded JSON object

Have a toJson() function inside your User class.

Of course, there are way more options - such as extending User so that User is not "contaminated", etc.

But yup, the general problem is your private properties.

csb
  • 674
  • 5
  • 13