Skip to content

Latest commit

 

History

History
501 lines (399 loc) · 15.5 KB

webfiori-json.md

File metadata and controls

501 lines (399 loc) · 15.5 KB

The Library WebFiori Json

In this page:

Introduction

When designing web services, the developer must decide on the response format at which the server will send back to the client after processing the request. One of the most widely used formats is called JSON. PHP does provide functions for encoding and decoding JSON using the methods json_encode(). And json_decode() but the two have some limitations. Since the framework promots the use of OOP approach, it uses a library called WebFiori Json to create well formatted JSON output.

Note: This library can be included using composer by including this entry in the require part of the composer.json file: "webfiori/jsonx":"*".

Library Structure

In most cases, the developer will have to use one class and one interface. The class Json is the core of the library. This class is the one which is used to create the final JSON and JSONx output. In addition to that, it can be used to parse JSON strings and convert them to Json objects.

The interface JsonI can be used to customize JSON and JSONx representation of objects which implement it when encoded. The interface has only one method which is JsonI::toJSON().

Usage Examples

The following code sample shows the most basic use case. It simply shows how to add a set of key/value pairs to be represented as JSON.

$jsonObj = new Json([
    'first-name' => 'Ibrahim',
    'last-name' => 'BinAlshikh',
    'age' => 26,
    'is-married' => true,
    'mobile-number' => null
]);

The JSON output that will be generated by the given code will be similiar to the following JSON:

{
    "first-name":"Ibrahim",
    "last-name":"BinAlshikh",
    "age":26,
    "is-married":true,
    "mobile-number":null
}

In addition to initializing your data using the consructor, it is possible to add more properties using one of the methods which can be used to add extra properties.

Adding Extra Properties

The method Json::add() can be used to add numbers, strings or objects , etc... to your JSON.

$jsonObj = new Json();
$jsonObj->add('first-name', 'Ibrahim');
$jsonObj->add('number', 45);
$jsonObj->add('another-number', 1.667);
$jsonObj->add('boolean', true);
$jsonObj->add('array', ['hello',77,88]);
$jsonObj->add('another-array', ['Bad',null, false]);   
{
    "first-name":"Ibrahim", 
    "number":45, 
    "another-number":1.667, 
    "boolean":true, 
    "array":[
        "hello", 
        77, 
        88
    ], 
    "another-array":[
        "Bad", 
        null, 
        false
    ]
}

In addition to the method Json::add(), there are other methods which are specific for adding specific types:

Working With Arrays

Arrays in PHP language can be associative, indexed or a mix of the two. When adding arrays to an instance of Json, the array can be added as an object or an array. This can be useful if the developer would like to convert an associative array to JSON object. The following code shows how the array will appear if added as indexed array.

$jsonObj = new Json();
$arr = [
    "one", 
    "two", 
    "assoc" => "ok"
];
$jsonObj->addArray("array", $arr);

The JSON that will be generated by the given code will be similar to the following:

{
    "array":[
        "one", 
        "two", 
        "ok"
    ]
}

In order to add the array as object, the developer must include extra parameter which tells the library to convert the array to JSON object when encoded.

$jsonObj = new Json();
$arr = [
    "one", 
    "two", 
    "assoc" => "ok"
];
$jsonObj->addArray("array", $arr, true);

The JSON that will be generated by the given code will be similar to the following:

{
    "array":{
        "0":"one", 
        "1":"two", 
        "assoc":"ok"
    }
}

More details about this feature can be found in the next section.

Adding Arrays as Objects

It is possible to add arrays as objects to Json instance. This can be achived using last parameter of the method Json::add(). Another option is to supply true for the last argument if the method Json::addArray() is used.

Note that if the index is associative, its key will be used as property name. If the array is indexed, the names of the properties will be numbers.

Note: If the array has sub-arrays and is added as object, sub arrays will also be added as objects.

Example 1: Indexed Array as Object

$jsonObj = new Json();
$arr = ["one", "two", 3, 3.5, "hello"];
$jsonObj->addArray("array", $arr, true);
{
    "array": {
        "0": "one",
        "1": "two",
        "2": 3,
        "3": 3.5,
        "4": "hello"
    }
}

Example 2: Associative Array as Object

$jsonObj = new Json();
$arr = [
    "one"=>1, 
    "two"=>2, 
    "assoc" => "ok"
];
$jsonObj->add("array", $arr, [
    'array-as-object' => true
]);
{
    "array": {
        "one": 1,
        "two": 2,
        "assoc": true
    }
}

Example 3: Indexed and Associative Array as Object

$jsonObj = new Json();
$arr = [
    "hello" => "World",
    "first-name" => "Ibrahim",
    "Random String",
    33,
    null,
    true,
    'is-good' => true,
    500
];
$jsonObj->addArray("array", $arr, true);
{
    "array": {
        "hello": "World",
        "first-name": "Ibrahim",
        "0": "Random String",
        "1": 33,
        "2": null,
        "3": true,
        "is-good": true,
        "4": 500
    }
}

Working With Objects

It is possible to add any object to an instance of Json but there is a catch here. If the object does not implement the interface JsonI, then the properties that will be added will depend on the public get methods of the object.

Object Does not Implement JsonI

Assuming that we would like to add an instance of the following class to an instance of Json:

class Employee {
    private $fName;
    private $lName;
    private $salary;
    public function __construct($fName, $lName, $salary) {
        $this->fName = $fName;
        $this->lName = $lName;
        $this->salary = $salary;
    }
    public function getFirstName() {
        return $this->fName;
    }
    public function getLastName() {
        return $this->lName;
    }
    public function getFullName() {
        return $this->getFirstName().' '.$this->getLastName();
    }
    public function salary() {
        return $this->salary;
    }
}

Also, assuming that we add the object as follows:

$jsonObj = new Json();

$jsonObj->addObject("obj", new Employee("Ibrahim", "BinAlshikh", 7200));

The JSON output that will be created will be similar to the following:

{
    "obj": {
        "FirstName": "Ibrahim",
        "LastName": "BinAlshikh",
        "FullName": "Ibrahim BinAlshikh"
    }
}

What happend here is the following, the method Json::addObject() will try to access the public methods of the instance. After that, it will search for the methods that has the prefix get in there name. Based on that, it will detect the name of the property. If the name of the method is getFirstName, the name of the proprty will be FirstName.

Note: The final name of the property will depend on the style of the properties names. For example, if properties style is set to snake, then the name of the proprty LastName would be last_name.

Object Implement JsonI

The interface JsonI is used to customize the generated JSON output of an object. The interface has one method at which the developer must implement which is JsonI::toJSON(). The developer must implement the method in a way it returns an instance of the class Json.

Assuming that we have the same Employee class from previous example, we can use the interface JsonI to customize JSON output as follows:

use webfiori\json\JsonI;
use webfiori\json\Json;

class MyClass implements JsonI {
    private $fName;
    private $lName;
    private $salary;
    public function __construct($fName, $lName, $salary) {
        $this->fName = $fName;
        $this->lName = $lName;
        $this->salary = $salary;
    }
    public function getFirstName() {
        return $this->fName;
    }
    public function getLastName() {
        return $this->lName;
    }
    public function getFullName() {
        return $this->getFirstName().' '.$this->getLastName();
    }
    public function salary() {
        return $this->salary;
    }

    public function toJSON() {
        return new Json([
            'first-name' => $this->getFirstName(),
            'last-name' => $this->getLastName(),
            'salary' => $this->salary()
        ]);
    }
}

JSON output of the given code would be similar to the following:

{
    "obj": {
        "first-name": "Ibrahim",
        "last-name": "BinAlshikh",
        "salary": 7200
    }
}

Converting JSON String to Json Object

The library supports converting JSON-like strings to Json instance. The static method Json::decode() is used to perform that task. This can be useful if the developer would like to add extra properties to JSON input which was sent by a web browser or HTTP client. The following code sample shows how to use the method.

$jsonObj =Json::decode('{"hello":"world","sub-obj":{},"an-array":["First Item"]}');
                
$jsonObj->get('sub-obj')->addMultiple([
    'first-name' => 'Ibrahim',
    'last-name' => 'BinAlshikh',
    'salary' => 7200
]);

$arr = $jsonObj->get('an-array');
$arr[] = "Second Item";
$jsonObj->add('an-array', $arr);

What the code doing is to add properties to the sub-obj and add one extra item to the array an-array. The JSON output will be similar to the following.

{
    "hello": "world",
        "sub-obj": {
        "first-name": "Ibrahim",
        "last-name": "BinAlshikh",
        "salary": 7200
    },
    "an-array": [
        "First Item",
        "Second Item"
    ]
}

Properties Style

It is possible to set a custom style for the properties to use. By default, the style is set to none. In this case, propery style will be exactly the same as when it was added. In addition to the none style, the class Json supports 3 styles, snake, kebab and camle.

Setting the style of the properties can be achived in two ways. The first one is to define a global constant with the name JSON_PROP_STYLE which is a string that has one of the values of the array Json::PROP_NAME_STYLES. If this constant is defined, it will be used by every instance of the class Json.

Another way to set the style is to use the method Json::setPropsStyle(). This method can be used to set specific style for one instance.

Snake Style Example

$jsonObj = new Json([
    'first-prop' => 1,
    'SecondProp' => 'Hello',
    'Third_prop' => true
]);
$jsonObj->setPropsStyle('snake');

The generated output will be similar to the following JSON:

{
    "first_prop": 1,
    "second_prop": "Hello",
    "third_prop": true
}

Kebab Style Example

$jsonObj = new Json([
    'first-prop' => 1,
    'SecondProp' => 'Hello',
    'Third_prop' => true
]);
$jsonObj->setPropsStyle('kebab');

The generated output will be similar to the following JSON:

{
    "first-prop": 1,
    "second-prop": "Hello",
    "third-prop": true
}

Camel Style Example

$jsonObj = new Json([
    'first-prop' => 1,
    'SecondProp' => 'Hello',
    'Third_prop' => true
]);
$jsonObj->setPropsStyle('camel');

The generated output will be similar to the following JSON:

{
    "firstProp": 1,
    "SecondProp": "Hello",
    "ThirdProp": true
}

Reading JSON File

One of the great features of the library is the ability to read any file that contains valid JSON and load it into an object of type Json. To achive this, the static method Json::fromFile() can be used. This method will return an object of type Json if the file content was parsed without issues. The following code sample shows how to use that method.

$jsonObj = Json::fromFile('jsonData.json');
if ($jsonObj instanceof Json) {
    // Do things with the data
} else {
    // Failed to read JSON data.
}

Converting to JSONx

JSONx is IBM standard for representing JSON as XML tree. The library provides full support for constructing JSONx. In order to get JSONx representation of Json instance, the method Json::toJSONxString()

$j = new Json(['bool-true'=>true,'bool-false'=>false]);
echo $j->toJSONxString();
<?xml version="1.0" encoding="UTF-8"?>
<json:object xsi:schemaLocation="http://www.datapower.com/schemas/json jsonx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
    <json:boolean name="bool-true">
        true
    </json:boolean>
    <json:boolean name="bool-false">
        false
    </json:boolean>
</json:object>

Next: Database Management

Previous: Sessions Management