JSON With PHP – A Complete Guide

So, you’ll have read the article: Understanding JSON and have a big picture what JSON is, well, in this article, we will dig more deep about json: “JSON in PHP” including some real-world example.

PHP support JSON since PHP 5.2 by introducing json_encode and json_decode function and continue to support it by fixed bugs and add more features.

Environment

Before going any further, you need to know that when writing this article, I’m using PHP version 5.6 running on Windows 10 operating system.

So, if you use a different version of PHP especially for the previous version, then you may get a different result as there are some bugs there.

I recommend using PHP >= 5.4 as these versions more mature in handling JSON.

I. Creating JSON With PHP

To create JSON with PHP as well as other programming languages, not recommended to create it manually, why? because risky, always use built-in function, in this case json_encode() instead.

Why should use built-in function?

Because every built-in function, including json_encode()  will take into account existing standards, so the resulting JSON can be assured valid and meet the existing standards (ECMA-404)

An example of json_encode() function:

$config = array(
		'site_title' =>'Webdevzoom'
		,'site_url'=>'http://webdevzoom.com'
		,'themes'=>'crystal'
	);
echo json_encode($config);
// Result
{"site_title":"Webdevzoom","site_url":"http:\/\/webdevzoom.com","themes":"crystal"}

I.1. Writing Term

json_encode() function has the following form:

json_encode ($ value [, int $ options = 0 [, int $depth = 512]])

Arguments:

  • The $value argument can be passed with all data types including objects and arrays excluding resources. The most used data type is array. In addition, The $value argument must be encoded using UTF-8, this often caused an error when creating JSON from database data.
  • The $options argument used to change the default parameters (we’ll discuss it later),  it can be passed using predefined constants.
  • $depth is the number of depth (child) of the $value.

Because the most used data type is array, so… for simplicity, we’ll only use this data type for the entire article.

I.2 json_encode() Basic Usage

We can use json_encode() function for indexed arrays, as well as associative arrays, or a combination of both, for example, we have a table in a database named config that contains the following data:

id option value
1 site_title Webdevzoom
2 site_description Web developer community for euthiast programmer
3 site_url http://webdevzoom.com
4 path user\htdocs\wdz
5 themes wdz

Example #1: Indexed Array

$conn = mysqli_connect('localhost', 'root', '', 'test');
$query = mysqli_query($conn, 'SELECT * FROM config');

while ($row = mysqli_fetch_assoc($query)) {
	$json[] = $row['value'];
}
echo '<pre>'; print_r($json); echo '</pre>';

$json = json_encode($json);
echo $json;

The result:

// ARRAY
Array
(
    [0] => Webdevzoom
    [1] => Web developer community for euthiast programmer
    [2] => http://webdevzoom.com
    [3] => user\htdocs\wdz
    [4] => wdz
)
// JSON with array data type
["Webdevzoom","Web developer community for euthiast programmer","http:\/\/webdevzoom.com","user\\htdocs\\wdz","wdz"]

Example #2: Associative Array

$conn = mysqli_connect('localhost', 'root', '', 'test');
$query = mysqli_query($conn, 'SELECT * FROM config');

while ($row = mysqli_fetch_assoc($query)) {
	$json['site_option'][ $row['option'] ] = $row['value'];
}
$json['site_db'] = array(
			'host' => 'localhost'
			, 'user' => 'root'
			, 'pass' => 'defult'
		);
					
echo '<pre>'; print_r($json); echo '</pre>';

$json = json_encode($json);
echo $json;

The result:

Array
(
    [site_option] => Array
        (
            [site_title] => Webdevzoom
            [site_description] => Web developer community for euthiast programmer
            [site_url] => http://webdevzoom.com
            [base_path] => user\htdocs\wdz
            [themes] => wdz
        )

    [site_db] => Array
        (
            [host] => localhost
            [user] => root
            [pass] => defult
        )

)
JSON with object data type
{"site_option":{"site_title":"Webdevzoom","site_description":"Web developer community for euthiast programmer","site_url":"http:\/\/webdevzoom.com","base_path":"user\\htdocs\\wdz","themes":"wdz"},"site_db":{"host":"localhost","user":"root","pass":"defult"}}

JSON object VS JSON array

From the above examples, we got two kinds of JSON data type: array and object. In PHP we don’t need to worry about that JSON data type as when we decode it PHP will convert all of them into PHP array (JSON object to an associative array and JSON array into an indexed array)  or PHP Object, so just focus on json_encode() function.

Learn more about JSON object and array data type: Understanding JSON – A Comprehensive Guide

Error while creating JSON data from a database

JSON is often used to display data from a database, like the examples above.

Data in a database might come from many places and may not be encoded using UTF-8, so when converting to JSON using json_encode() may resulting an error:

Malformed UTF-8 characters, possibly incorrectly encoded

To solve that, you can read the article: JSON Error In PHP – Creating JSON From Database

The importance of escaping slash character (\/)

By default, Starting from PHP 5.4.0, the json_encode() function will automatically escape any slash character, e.g. from / to\/

With such behavior, for url, will look bit mess, eg: http://webdevzoom.com/images/json_logo.png become http:\/\/webdevzoom.com\/images\/json_logo.png

In JSON standard, escaping slash is optional, not mandatory, if we don’t want it, we can add JSON_UNESCAPE_SLASH in options argument.

So, what are the benefits of escaping slash?

The main purpose is to prevent script execution.

If a JSON string contains a closing tag </script>, and then placed within <script> tag, it will cause the main script stopped and javascript code within the JSON string will be executed, for example:

<script type = "text/javascript">
var json = {"content": "</script><script>alert(document.cookie)</script>"}
</script>

In the above example, the javascript code in the JSON string will be executed, this is dangerous and potentially arise XSS attacks.

So… we should let the slash character escaped, or we can escape it if we really sure that the content of the JSON string is safe.

I.3 json_encode() Second Argument

The json_encode() function provides an optional second argument that can be used to change default parameters, actually, the value of this option are bitmasks: 1, 2, 4, 8, 16, etc., but to make it easier, PHP has provided constants representing that values, such as:

  1. JSON_HEX_TAG to convert HTML tags (<) and (>) to \ u003C and \ u003E
  2. JSON_HEX_APOS to convert the single quote (‘) to \ u0027. This is helpful when putting JSON into the HTML element attribute.
  3. JSON_HEX_QUOT to convert double quote (“) to \ u0022
  4. JSON_HEX_AMP to convert (&) to \ u0026
  5. JSON_PRETTY_PRINT to format JSON output by adding space characters (not tabs). It makes the JSON string more readable. This option exists on PHP  >= 5.4.0. An example:
    $array = array('site_title' => 'Webdevzoom', 'site_url' => 'http://webdevzoom.com');
    
    echo json_encode($array);
    // Result: {"site_title":"Webdevzoom","site_url":"http:\/\/webdevzoom.com"}
    
    echo json_encode($array, JSON_PRETTY_PRINT);
    // Result: 
    {
        "site_title": "Webdevzoom",
        "site_url": "http:\/\/webdevzoom.com"
    }
  6. JSON_UNESCAPED_SLASHES to not escape the slash character (/), for example:
    $array = array('site_title' => 'Webdevzoom', 'site_url' =>'http://webdevzoom.com/blog/');
    
    echo json_encode($array);
    // Result: {"site_title":"Webdevzoom","site_url":"http:\/\/webdevzoom.com\/blog\/"}
    
    echo json_encode($array, JSON_UNESCAPED_SLASHES);
    // Hasil: {"site_title":"Webdevzoom","site_url":"http://webdevzoom.com/blog/"}
  7. JSON_FORCE_OBJECT. Force the resulting JSON string to object instead of array. This is useful if the recipient requires that the JSON string should be an object. Example:
    $array = array('Webdevzoom', 'http://webdevzoom.com/blog/');
    
    echo json_encode($array);
    // Result an array: ["Webdevzoom","http:\/\/webdevzoom.com\/blog\/"]
    
    echo json_encode($array, JSON_FORCE_OBJECT);
    // Result an object: {"0":"Webdevzoom","1":"http:\/\/webdevzoom.com\/blog\/"}

The above constants are the most used, if you want to know all list of constants, you can visit the official page: PHP: Predefined Constant.

To use more than one option, use bitwise OR (|), for example:

$json = array('html' => '<div class="title">Example</div>');
$encode = json_encode($json, JSON_HEX_TAG | JSON_HEX_QUOT);

II. Parsing JSON With PHP

So we have known how to create JSON with PHP, now, we discuss how to convert the JSON string back to data that will make us easy to work with.

In PHP, JSON string can be converted into two forms: array and object. To convert JSON string to both array and object we use json_decode() function. This function has the following form:

json_decode( string $json [, bool $assoc = FALSE [, int $depth = 512 [, int $options = 0 ]]] )

The $json argument is mandatory, while others are optional. If the second argument $assoc is set to true, then the output is a PHP array, otherwise PHP object, for example, we have the JSON string as follows:

$json = '{"site_option":
		{"site_title":"Webdevzoom"
		  ,"site_description":"Web developer community for euthiast programmers"
		  ,"site_url":"http://webdevzoom.com"
		  ,"themes":"wdz"
		}
	  ,"site_db":
		{"host":"localhost"
		  ,"user":"root"
		  ,"pass":"defult"
		}
	}';

Example #1: Result an object:

$decode = json_decode($json);
var_dump($decode);

/* Result:
object(stdClass)#1 (2) {
  ["site_option"]=>
  object(stdClass)#2 (4) {
    ["site_title"]=>
    string(10) "Webdevzoom"
    ["site_description"]=>
    string(48) "Web developer community for euthiast programmers"
    ["site_url"]=>
    string(21) "http://webdevzoom.com"
    ["themes"]=>
    string(3) "wdz"
  }
  ["site_db"]=>
  object(stdClass)#3 (3) {
    ["host"]=>
    string(9) "localhost"
    ["user"]=>
    string(4) "root"
    ["pass"]=>
    string(6) "defult"
  }
}
*/

Example #2: Result an array:

$decode = json_decode($json, true);
echo '<pre>'; print_r($decode); echo '</pre>';

/*Result:
Array
(
    [site_option] => Array
        (
            [site_title] => Webdevzoom
            [site_description] => Web developer community for euthiast programmers
            [site_url] => http://webdevzoom.com
            [themes] => wdz
        )
    [site_db] => Array
        (
            [host] => localhost
            [user] => root
            [pass] => defult
        )
)
*/

Prefer Object or Array? it depends on the situation, generally, people use arrays, but if they are in Object Oriented Environment, object is more convenience.

NOTE:

JSON string can come from many sources: e.g from databases, files (.txt, .json, etc.), or from external URLs, in order to make this post not too weight, this topic discussed in another article.

III. Handling Error On JSON

When using json_encode() and json_encode() functions and an error occurred, then both functions do not generate any error messages, json_encode() results an empty value, while for json_decode() results a NULL value

Well, to know that an error occurs, we can use one of the following two functions:

  1. json_last_error()
    This function available since PHP  5.3.0, it will generate an integer value (that has a certain meaning) as a result of the execution json_encode() and json_decode() functions.
  2. json_last_error_msg()
    This function available in since PHP 5.5.0, the function will directly generate a string that reflects the execution of the json_encode() and json_decode() functions.

The easiest way to find out the error is to use the json_last_error_msg() function as it directly tell us what just happened, for example:

$json = '{"site_option":
		{"site_title":"Webdevzoom"
		  ,"site_url":"http://webdevzoom.com"
		}
	 }';
$decode = json_decode($json, true);
$last_error = json_last_error_msg();	
if (strtolower($last_error) != 'no error') {
	echo 'ERROR: ' . $last_error; die;
}

NOTE: In the above example, if no error occurs, the json_last_error_msg() will result the string “No error” so we evaluate it using if(strtolower($ last_error) != 'no error'))

To be more flexible and more organized in handling error messages, we can use the function json_last_error() This function will generate an integer ranging from 0 s.d 10

This integer value has been translated to constants as follows:

Error Code and The Meaning
Constant Integer Mean PHP Version
JSON_ERROR_NONE 0 No error has occurred
JSON_ERROR_DEPTH 1 The maximum stack depth has been exceeded
JSON_ERROR_STATE_MISMATCH 2 Invalid or malformed JSON
JSON_ERROR_CTRL_CHAR 3 Control character error, possibly incorrectly encoded
JSON_ERROR_SYNTAX 4 Syntax error
JSON_ERROR_UTF8 5 Malformed UTF-8 characters, possibly incorrectly encoded PHP 5.3.3
JSON_ERROR_RECURSION 6 One or more recursive references in the value to be encoded PHP 5.5.0
JSON_ERROR_INF_OR_NAN 7 One or more NAN or INF
values in the value to be encoded
PHP 5.5.0
JSON_ERROR_UNSUPPORTED_TYPE 8 A value of a type that cannot be encoded was given PHP 5.5.0
JSON_ERROR_INVALID_PROPERTY_NAME 9 A property name that cannot be encoded was given PHP 7.0.0
JSON_ERROR_UTF16 10 Malformed UTF-16 characters, possibly incorrectly encoded PHP 7.0.0

So… if we echo that constant we’ll get the integer value, e.g echo JSON_ERROR_SYNTAX then we’ll get 4

Using that kind of error handling, make us possible to customize the error message. This is useful for example for localization, we can translate the error message to different languages.

Example of using constant:

$json = '{"title":"Understansing JSON - Part II}';
$decode = json_decode($json);
if (json_last_error() == JSON_ERROR_UTF8) {
	echo 'ERROR: Your data contains non UTF-8 encoded character';
}

Using integer:

if (json_last_error() == 5) {
	echo 'ERROR: Your data contains non UTF-8 encoded character';
}

To handle all error messages, we can create an array that contains all possible error:

$json_error = array {
	JSON_ERROR_DEPTH => 'Maximum stach depth exceed, try to increase the depth limit'
	, JSON_ERROR_STATE_MISMATCH => 'Invalid JSON form'
	, JSON_ERROR_CTRL_CHAR => 'Control character error, make sure your string use UTF-8 encoding'
	, JSON_ERROR_SYNTAX => 'Syntax error'
	, JSON_ERROR_UTF8 => 'Invalid character, make sure your string use UTF-8 encoding'
	, JSON_ERROR_RECURSION => 'One or more recursive references in the value to be encoded'
	, JSON_ERROR_INF_OR_NAN => 'Your string contains INF or NAN value'
	, JSON_ERROR_UNSUPPORTED_TYPE => 'A value of a type that cannot be encoded'
	, JSON_ERROR_INVALID_PROPERTY_NAME  => 'A property name of JSON that cannot be encoded'
	, JSON_ERROR_UTF16 => 'Invalid UTF-16 characters, make sure you string corectly encoded'
}

$json = '{"title":"Understanding JSON in PHP - Part II}';
$decode = json_decode($json, true);

$last_error = json_last_error();
if ($last_error == 0) {
	print_r($decode);
} else {
	echo $json_error[$last_error];
}

IV. JSON and XSS

Any string associated with javascript and HTML will have a risk of XSS attack, as well as JSON string.

An XSS attack happens when the HTML code contains <script> tag that comes from an untrusted source (such as an input form of a website, where visitors may inject any malicious script).

That script tag contains a javascript code that will expose any sensitive data and send them to some place that have been specified by the script maker.

Related to JSON, creating JSON with json_encode() function is secure, because (as previously mentioned) the function has escaped slash (<\/script>) – starting from PHP version 5.4.0 -, so javascript code inside JSON will not be executed.

Moreover, the protection of XSS attack should be done before we use that data, e.q., filtering input form before inserting into the database, filtering query string from URL before using it, etc…

So when we want to use that data, e.q creating a JSON string or other purposes,  they are already sanitized and safe.

Do we need HEX option?

Discussion that often arises is if our JSON contains HTML tags, or <script> tags, should we use the option JSON_HEX_XXX to convert HTML element into hex value? such as the following?

$array = array('html' => '</script><script>document.cookie</script>');
$json = json_encode($json, JSON_HEX_TAG | JSON_HEX_QUOT | JSON_HEX_APOS | JSON_HEX_AMP);

Again, the json_encode() function is secure so that the use of JSON_HEX_xxx argument is no longer necessary.

Moreover, we don’t need that if we trust the data source, e.g. from our own server and we created that data, or we really sure that the data already sanitized well.

V. Wrap Up

PHP provides complete built-in tools to work with JSON, things to note is the version of PHP, because in PHP < 5.6, there are some bugs that are sometimes troublesome.

Happy encoding !!!.

Subscibe Now

Loves articles on webdevzoom.com? join our newsletter to get quality article right to your inbox. Nothing else, just quality stuff!!!

Our Commitment: We respect your privacy, we'll not share your credential to any party

Leave a comment

Like Us

Newsletter

Great information from webdevzoom.com right to your inbox

  1. JSON in HTML Document

  2. JSON With PHP – A Complete Guide

  3. Understanding JSON – A Comprehensive Guide

  4. 7 Best Free Online Image Compressor & Optimizer Tools – Compared & Tested

  5. 40+ Modern Free WordPress Themes For Blog in 2017 – Beautiful & Responsive

  6. Understanding Constant in PHP – Updated to PHP 7

  7. Understanding Variable in PHP – All PHP Version

  8. Retrieve Data From Multiple Tables in MySQL – JOIN in MySQL

  9. How to Calculate Date and Time Difference in PHP – The Easiest Way

  10. Understanding Time, Mktime, and Strtotime Function in PHP