In this page:
- Introduction
- Library Structure
- Usage Example
- Adding Extra Properties
- Working With Arrays
- Working With Objects
- Converting JSON String to Json Object
- Properties Style
- Reading JSON File
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 thecomposer.json
file:"webfiori/jsonx":"*"
.
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()
.
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.
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:
Json::addArray()
. Used to add arrays.Json::addBoolean()
. Used to add boolean value (true
orfalse
).Json::addNumber()
. Used to add numbers (integers or floats).Json::addObject()
. Used to add PHP objects.
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.
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.
$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"
}
}
$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
}
}
$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
}
}
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.
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 proprtyLastName
would belast_name
.
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
}
}
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"
]
}
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.
$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
}
$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
}
$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
}
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.
}
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