In this page:
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.
Code
$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:
Code
{
"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.
Code
$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]);
Code
{
"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
or
false
).
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.
Code
$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:
Code
{
"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.
Code
$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:
Code
{
"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.
Code
$jsonObj = new Json();
$arr = ["one", "two", 3, 3.5, "hello"];
$jsonObj->addArray("array", $arr, true);
Code
{
"array": {
"0": "one",
"1": "two",
"2": 3,
"3": 3.5,
"4": "hello"
}
}
Code
$jsonObj = new Json();
$arr = [
"one"=>1,
"two"=>2,
"assoc" => "ok"
];
$jsonObj->add("array", $arr, [
'array-as-object' => true
]);
Code
{
"array": {
"one": 1,
"two": 2,
"assoc": true
}
}
Code
$jsonObj = new Json();
$arr = [
"hello" => "World",
"first-name" => "Ibrahim",
"Random String",
33,
null,
true,
'is-good' => true,
500
];
$jsonObj->addArray("array", $arr, true);
Code
{
"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.
JsonI
Assuming that we would like to add an instance of the following class to an instance of
Json
:
Code
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;
}
}</code></pre>
<p>Also, assuming that we add the object as follows:</p>
<pre><code class="language-php">$jsonObj = new Json();
$jsonObj->addObject("obj", new Employee("Ibrahim", "BinAlshikh", 7200));
</code></pre>
<p>The JSON output that will be created will be similar to the following:</p>
<pre><code class="language-json">{
"obj": {
"FirstName": "Ibrahim",
"LastName": "BinAlshikh",
"FullName": "Ibrahim BinAlshikh"
}
}</code></pre>
<p>What happend here is the following, the method <a href="https://webfiori.com/docs/webfiori/json/Json#addObject"><code>Json::addObject()</code></a> will try to access the public methods of the instance. After that, it will search for the methods that has the prefix <code>get</code> in there name. Based on that, it will detect the name of the property. If the name of the method is <code>getFirstName</code>, the name of the proprty will be <code>FirstName</code>.</p>
<blockquote>
<p><strong>Note:</strong> The final name of the property will depend on the style of the properties names. For example, if properties style is set to <code>snake</code>, then the name of the proprty <code>LastName</code> would be <code>last_name</code>.</p>
</blockquote>
<h3>Object Implement <code>JsonI</code></h3>
<p>The interface <a href="https://webfiori.com/docs/webfiori/json/JsonI"><code>JsonI</code></a> is used to customize the generated JSON output of an object. The interface has one method at which the developer must implement which is <a href="https://webfiori.com/docs/json/JsonI#toJSON"><code>JsonI::toJSON()</code></a>. The developer must implement the method in a way it returns an instance of the class <a href="https://webfiori.com/docs/webfiori/json/Json"><code>Json</code></a>.</p>
<p>Assuming that we have the same <code>Employee</code> class from previous example, we can use the interface <code>JsonI</code> to customize JSON output as follows:</p>
<pre><code class="language-php">
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:
Code
{
"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.
Code
$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.
Code
{
"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.
Code
$jsonObj = new Json([
'first-prop' => 1,
'SecondProp' => 'Hello',
'Third_prop' => true
]);
$jsonObj->setPropsStyle('snake');
The generated output will be similar to the following JSON:
Code
{
"first_prop": 1,
"second_prop": "Hello",
"third_prop": true
}
Code
$jsonObj = new Json([
'first-prop' => 1,
'SecondProp' => 'Hello',
'Third_prop' => true
]);
$jsonObj->setPropsStyle('kebab');
The generated output will be similar to the following JSON:
Code
{
"first-prop": 1,
"second-prop": "Hello",
"third-prop": true
}
Code
$jsonObj = new Json([
'first-prop' => 1,
'SecondProp' => 'Hello',
'Third_prop' => true
]);
$jsonObj->setPropsStyle('camel');
The generated output will be similar to the following JSON:
Code
{
"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.
Code
$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()
Code
$j = new Json(['bool-true'=>true,'bool-false'=>false]);
echo $j->toJSONxString();
Code
<?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