Bridging the gap between data and code

I don’t know about you, but I absolutely love JSON. JSON, or JavaScript Object Notation, is a way to store and transport data. Whether we’re generating JSON objects to be sent from the server or accepting JSON objects from the client, we need to understand the JSON format. Don’t think too much into it: JSON is just a string.

JSON can start with either a bracket ( [ ) or a curly brace ( { ). Either works. The object is represented with a curly brace and an ordered list starts with a bracket.

The object has key/value pairs, whereas the array does not.

// Array Notation
[
   "Dino Cajic",
   "Frank Johnson",
   "Steven Brown"
]
// Object Notation
{
   "name":"Dino Cajic",
   "age":102,
   "email":"dino@example.com"
}

You can also create an array of objects.

[
   {
      "name":"Dino Cajic",
      "age":102,
      "email":"dino@example.com"
   },
   {
      "name":"Frank Johnson",
      "age":50,
      "email":"frank@example.com"
   }
]

We’ve looked at a few data types above:

  • array
  • object
  • string
  • number

But we can also send boolean values and the null value.

[
   {
      "name":"Dino Cajic",
      "age":102,
      "email":"dino@example.com",
      "isWriting":true,
      "tailColor":null
   },
   {
      "name":"Frank Johnson",
      "age":50,
      "email":"frank@example.com",
      "isWriting":false,
      "tailColor":null
   }
]

Creating a JSON object with PHP

Now that we understand the format, let’s see how we can create a JSON object with PHP. It’s actually really simple. We use the json_encode built in function. The json_encode function accepts either an array or an object and converts it into a string.

Lets look at a few examples to see how this conversion happens.

<?php

$array = ["Dino Cajic", "Steven Johnson", "Fred Smith"];

echo json_encode($array);

The output is: [“Dino Cajic”,”Steven Johnson”,”Fred Smith”].

Since the array is not an associative array, it creates an array. Let’s look at an associative array example.

<?php

$array = [
    "name" => "Dino Cajic",
    "age" => 102,
    "email" => "dino@example.com",
    "isWriting" => true,
    "tailColor" => null
];

echo json_encode($array);

The output this time is an object:

{
   "name":"Dino Cajic",
   "age":102,
   "email":"dino@example.com",
   "isWriting":true,
   "tailColor":null
}

What if we have a mixed array?

<?php

$array = [
    "name" => "Dino Cajic",
    "age" => 102,
    "email" => "dino@example.com",
    true,
    null
];

echo json_encode($array);

We actually still get an object, but the index values are added instead of the named keys.

{
   "name":"Dino Cajic",
   "age":102,
   "email":"dino@example.com",
   "0":true,
   "1":null
}

We can also create a JSON from an object. Any publicly available properties will be converted into JSON keys and the values that they contain will be be the values.

<?php

class PublicObject
{
    public string $name;
    public int $age;
    public string $email;
    public bool $isWriting;
    public ?string $tailColor;

    public function __construct($data) {
        $this->name      = $data['name'];
        $this->age       = $data['age'];
        $this->email     = $data['email'];
        $this->isWriting = $data['isWriting'];
        $this->tailColor = $data['tailColor'];
    }
}

$publicObject = new PublicObject([
    "name"      => "Dino Cajic",
    "age"       => 102,
    "email"     => "dino@example.com",
    "isWriting" => true,
    "tailColor" => null
]);

echo json_encode($publicObject);

The response that we get is:

{
   "name":"Dino Cajic",
   "age":102,
   "email":"dino@example.com",
   "isWriting":true,
   "tailColor":null
}

What if we made a few of those properties private? For example, if we set the $isWriting and $tailColor properties private. The JSON output just removes them from the string.

{
   "name":"Dino Cajic",
   "age":102,
   "email":"dino@example.com"
}

But what if we wanted to see them regardless? Well, we could implement the __toString magic method and call our json_encode there. Or we could create really any method, like toJSON and call it there. Let’s look at __toString.

<?php

class PrivateObject
{
    private string $name;
    private int $age;
    private string $email;
    private bool $isWriting;
    private ?string $tailColor;

    public function __construct($data) {
        $this->name      = $data['name'];
        $this->age       = $data['age'];
        $this->email     = $data['email'];
        $this->isWriting = $data['isWriting'];
        $this->tailColor = $data['tailColor'];
    }

    public function __toString() {
        return json_encode([
            "name"      => $this->name,
            "age"       => $this->age,
            "email"     => $this->email,
            "isWriting" => $this->isWriting,
            "tailColor" => $this->tailColor
        ]);
    }
}

$privateObject = new PrivateObject([
    "name"      => "Dino Cajic",
    "age"       => 102,
    "email"     => "dino@example.com",
    "isWriting" => true,
    "tailColor" => null
]);

echo $privateObject;

There is also a JsonSerializable interface that we can implement. The output that we get is the same.

<?php

class JsonSerializableTest implements JsonSerializable
{
    private string $name;
    private int $age;
    private string $email;
    private bool $isWriting;
    private ?string $tailColor;

    public function __construct($data) {
        $this->name      = $data['name'];
        $this->age       = $data['age'];
        $this->email     = $data['email'];
        $this->isWriting = $data['isWriting'];
        $this->tailColor = $data['tailColor'];
    }

    public function jsonSerialize()
    {
        return [
            "name"      => $this->name,
            "age"       => $this->age,
            "email"     => $this->email,
            "isWriting" => $this->isWriting,
            "tailColor" => $this->tailColor
        ];
    }
}

$jsonSerializableTest = new JsonSerializableTest([
    "name"      => "Dino Cajic",
    "age"       => 102,
    "email"     => "dino@example.com",
    "isWriting" => true,
    "tailColor" => null
]);

echo json_encode($jsonSerializableTest);

The only difference was that with __toString, I wrapped the json_encode function inside the function itself, whereas the jsonSerialize method just returns the array.

Reading JSON objects with PHP

Now that we know how to create (encode) a JSON object, we should also know how to read (decode) a JSON object that’s sent from the client. We’re not going to go too much into the actual sending of the array, since that’s handled through the frontend, but I will show you a couple of examples.

The simplest example is to create the JSON string in PHP and using the json_decode built in function to test it.

<?php

$encoded_json = '{"name":"Dino Cajic","age":102,"email":"dino@example.com","isWriting":true,"tailColor":null}';
$decoded_json = json_decode($encoded_json);

var_dump($decoded_json);

Since this is an object representation, we are going to get an actual object.

/app/100 JSON/JsonDecode.php:6:
object(stdClass)[1]
  public 'name' => string 'Dino Cajic' (length=10)
  public 'age' => int 102
  public 'email' => string 'dino@example.com' (length=16)
  public 'isWriting' => boolean true
  public 'tailColor' => null

That means that we can now call the properties the exact same way that we normally would our objects, with the object operator ->.

<?php

$encoded_json = '{"name":"Dino Cajic","age":102,"email":"dino@example.com","isWriting":true,"tailColor":null}';
$decoded_json = json_decode($encoded_json);

var_dump($decoded_json->name);
/app/100 JSON/JsonDecode.php:6:string 'Dino Cajic' (length=10)

Lets look at an array example.

<?php
$encoded_json = '["Dino Cajic", "Steven Johnson", "Fred Smith"]';
$decoded_json = json_decode($encoded_json);

var_dump($decoded_json);

This time, we get a simple array.

/app/100 JSON/JsonDecode.php:13:
array (size=3)
  0 => string 'Dino Cajic' (length=10)
  1 => string 'Steven Johnson' (length=14)
  2 => string 'Fred Smith' (length=10)

To access array elements, we’ll need to use the index values.

<?php
$encoded_json = '["Dino Cajic", "Steven Johnson", "Fred Smith"]';
$decoded_json = json_decode($encoded_json);

var_dump($decoded_json[0]);
/app/100 JSON/JsonDecode.php:14:string 'Dino Cajic' (length=10)

How else can we send JSON objects to the backend? Let’s look at Postman.

Click on the Body and select Raw. Paste your JSON object. For this instance, POST is set as the request type, but it doesn’t matter. You wont actually be able to read the content via $_POST; you’ll need to use php://input, “which is a read-only stream that allows you to read raw data from the request body.” (https://www.php.net/manual/en/wrappers.php.php).

<?php
$json_encoded = file_get_contents('php://input');
$json_decoded = json_decode( $json_encoded );

var_dump( $json_decoded );

The output that we receive in Postman can be seen below.

There are many other ways to send JSON to the backend; it all depends on the frontend library that you’re using. You could also use JSON.stringify with plain JavaScript or even do something with Ajax.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Send JSON</title>
</head>
<body>
    <div id="result"></div>
    
    <script>
        let data = {
            "name":"Dino Cajic",
            "age":102,
            "email":"dino@example.com",
            "isWriting":true,
            "tailColor":null
        };

        let xhr = new XMLHttpRequest();

        xhr.open("POST", "http://0.0.0.0/100%20JSON/JsonDecodeRequest.php");
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                let div = document.getElementById("result");
                div.innerHTML = xhr.responseText;
            }
        }

        xhr.setRequestHeader("Content-type", "application/json")
        xhr.send( JSON.stringify(data) );
    </script>
</body>
</html>

I hope this helps to demystify the way PHP and JSON work together.

https://github.com/dinocajic/php-youtube-tutorials?source=post_page—–e91d243abe3c——————————–

 

SCOPE SURPRISES IN PHP: THE JOY OF DEBUGGING

PHP – P107: SCOPE QUIRKS

Scope defines variable visibility in a program. Variables in functions are isolated; others can’t access them.

Bridging the gap between data and code

PHP – P108: json

JSON, or JavaScript Object Notation, is a way to store and transport data. Whether we’re generating JSON objects to be sent from the server or accepting JSON objects from the client, we need to understand the JSON format.

CODE’S WAY OF SOLVING PROBLEMS WITHIN ITSELF

PHP – P109: RECURSION

Recursion is not a PHP topic, but I’ve been asked about it so frequently that I thought we would do an article on it. It has been a fun ride and thanks for reading along on this PHP series.

Leave a Reply