Unit testing of json encoding/decoding against errors - php

So basically I have the code which is giving me the message from json_last_error():
$msg = 'Unknown error';
switch (json_last_error()) {
case JSON_ERROR_NONE:
$msg = null;
break;
case JSON_ERROR_DEPTH:
$msg = 'Maximum stack depth exceeded';
break;
case JSON_ERROR_STATE_MISMATCH:
$msg = 'Underflow or the modes mismatch';
break;
case JSON_ERROR_CTRL_CHAR:
$msg = 'Unexpected control character found';
break;
case JSON_ERROR_SYNTAX:
$msg = 'Syntax error, malformed JSON';
break;
case JSON_ERROR_UTF8:
$msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
break;
}
return $msg;
For testing purposes I want to raise all the errors from this list to have 100% coverage, but I can't raise JSON_ERROR_STATE_MISMATCH.
Can anyone help giving me the example with either encoding or decoding, with any parameters, which can produce this error?

$j = '{"j": 1 ] }';
json_decode($j);
var_dump(json_last_error() === JSON_ERROR_STATE_MISMATCH); // true
How I found it: just checked the source code :-)

Related

Why does using json_decode on this JSON string result in a null value

"op=add&item={"firstName":"test","lastName":"test","email":"test%40test.com","password":"test"}"
I'm passing the JSON body above to my PHP backend and when trying to use json_decode on it, it results in null. I've used json_last_error() and it states there is a syntax issue. Using jsonlint.com, it gives me this error:
Error: Parse error on line 1:
"op=add&item={"firstName ":"test "
---------------^
Expecting 'EOF', '}', ':', ',', ']', got 'undefined'
I've tried troubleshooting this error but haven't been able to get a successful response. Can someone describe what the issue could be?
For json_decode() to work, it requires a string.
Looking at you syntax, it seems the outer quotes aren't correct.
Yours:
"op=add&item={"firstName":"test","lastName":"test","email":"test%40test.com","password":"test"}"
As they should be:
'op=add&item={"firstName":"test","lastName":"test","email":"test%40test.com","password":"test"}'
If you use single quotes, it's a correct string. Which can be decoded.
Your "body" isn't a JSON string, only the item parameter content looks like one. Take that content and pass to the function json_decode.
Example:
json_decode($_GET['item']);
this is a useful function to debug json issues
function json_validate($string){
// decode the JSON data
$result = json_decode($string);
// switch and check possible JSON errors
switch (json_last_error()) {
case JSON_ERROR_NONE:
$error = ''; // JSON is valid // No error has occurred
break;
case JSON_ERROR_DEPTH:
$error = 'The maximum stack depth has been exceeded.';
break;
case JSON_ERROR_STATE_MISMATCH:
$error = 'Invalid or malformed JSON.';
break;
case JSON_ERROR_CTRL_CHAR:
$error = 'Control character error, possibly incorrectly encoded.';
break;
case JSON_ERROR_SYNTAX:
$error = 'Syntax error, malformed JSON.';
break;
// PHP >= 5.3.3
case JSON_ERROR_UTF8:
$error = 'Malformed UTF-8 characters, possibly incorrectly encoded.';
break;
// PHP >= 5.5.0
case JSON_ERROR_RECURSION:
$error = 'One or more recursive references in the value to be encoded.';
break;
// PHP >= 5.5.0
case JSON_ERROR_INF_OR_NAN:
$error = 'One or more NAN or INF values in the value to be encoded.';
break;
case JSON_ERROR_UNSUPPORTED_TYPE:
$error = 'A value of a type that cannot be encoded was given.';
break;
default:
$error = 'Unknown JSON error occured.';
break;
}
if ($error !== '') {
// throw the Exception or exit // or whatever :)
exit($error);
}
// everything is OK
return $result;
}

How to use match expression instead of switch expression

We can use match expression instead of switch case in PHP 8.
How to write match expression correctly for the following switch case?
switch($statusCode) {
case 200:
case 300:
$message = null;
break;
case 400:
$message = 'not found';
break;
case 500:
$message = 'server error';
break;
default:
$message = 'unknown status code';
break;
}
There is an important thing that must remember with match. It is type sensitive, not as a switch statement. Thus it's very important to cast the variable properly. In the case of HTTP codes often it is sent in string format, e.g. "400".
It may give a lot of pain during debugging when we don't know about it. If $statusCode was a string, the default option would be always invoked. My modified version of an accepted answer:
$message = match((int) $statusCode) {
200, 300 => null,
400 => 'not found',
500 => 'server error',
default => 'unknown status code',
};

PHP Fatal Error from json_decode inside try-catch

The following code throws me this exception:
$return = json_decode($result);
Fatal error: Cannot access property started with '\0' in
file.php on line
36
I've read php documentation and some questions here, so I've tried this code:
try{
$return = json_decode($result);
}
catch(Exception $e)
{
$json_error_code = json_last_error();
echo $json_error_code . ",";
$err.= 'JSON parse error';
switch ($json_error_code) {
case JSON_ERROR_NONE:
$err = "NONE";
break;
case JSON_ERROR_DEPTH:
$err.= ' - Maximum stack depth exceeded';
break;
case JSON_ERROR_STATE_MISMATCH:
$err.= ' - Underflow or the modes mismatch';
break;
case JSON_ERROR_CTRL_CHAR:
$err.= ' - Unexpected control character found';
break;
case JSON_ERROR_SYNTAX:
$err.= ' - Syntax error, malformed JSON';
break;
case JSON_ERROR_UTF8:
$err.= ' - Malformed UTF-8 characters, possibly incorrectly encoded';
break;
default:
$err.= ' - Unknown error';
break;
}
echo $err;
}
It throws the same Fatal error - in a try-catch block!
Can someone help me solve this?
Thanks!
Firstly remove try catch block json_decode does not throw exceptions.
Secondly create $err change the line
$err.= 'JSON parse error';
to
$err= 'JSON parse error';
You try to do concatenate strings to variable that does not exists.
Remove also break from default: it's useless.
After you do it it should work.
Notice: If you want errors to behave like exceptions you need to use own error handler
If json_encode gives you fatal error then try reinstalling json extension and see https://bugs.php.net/bug.php?id=68546

JSON encode gives "malformed json" error on a file that is completely valid JSON

So, i'm creating php page that sends JSON data to other app. I got the code working, but then it mysteriosly stopped working. I'm getting malformed JSON error, even though JSON validator says my file is fine. When i try other JSON file it works fine.
Here's the JSON:
[{
"value1": "Example",
"value2": "Other example"
}]
And here's the PHP (don't mind the Finnish variable names):
$url = "velat.json";
$velat_json = file_get_contents($url);
$velatarray = array();
$velat = json_decode($velat_json);
switch (json_last_error()) {
case JSON_ERROR_NONE:
echo ' - No errors';
break;
case JSON_ERROR_DEPTH:
echo ' - Maximum stack depth exceeded';
break;
case JSON_ERROR_STATE_MISMATCH:
echo ' - Underflow or the modes mismatch';
break;
case JSON_ERROR_CTRL_CHAR:
echo ' - Unexpected control character found';
break;
case JSON_ERROR_SYNTAX:
echo ' - Syntax error, malformed JSON';
break;
case JSON_ERROR_UTF8:
echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
break;
default:
echo ' - Unknown error';
break;
}
foreach($velat as $velka){
$velatarray[] = $velka;
}
header("Access-Control-Allow-Origin: *"); //CORS
header("Content-type: application/json");
print json_encode($velatarray, JSON_PRETTY_PRINT);
What's really weird is that it USED to work. I added feature that allowed me to add new items to JSON file via angular app and even that worked. Then i deleted the added item manually and tried encoding it in utf-8 and suddenly it stopped working, even after i undid all changes and reversed it back to bare bones. How is this happening?
Edit: fixed, BOM was causing the issue

Get the data from json url using php?

This is a json api : https://jobs.github.com/positions.json?description=java&page=1
I want get the data from this url.
<?php
$url = file_get_contents('https://jobs.github.com/positions.json?description=java&page=1');
var_dump(json_decode($url,true)); ?>
this code return null
I also check the url in json validator: http://jsonformatter.curiousconcept.com/ the json is valid but i con't able get the data from this url please help me...
Try this script to determine what the problem is. If there is no JSON module installed (see #julian comment), you can try to use PHP implementations of JSON like this: http://pear.php.net/pepr/pepr-proposal-show.php?id=198
if (! extension_loaded('json')) {
echo 'Module JSON not available!';
exit();
}
$url = file_get_contents('https://jobs.github.com/positions.json?description=java&page=1');
$data = json_decode($url,true);
switch (json_last_error()) {
case JSON_ERROR_NONE:
echo ' - No errors';
break;
case JSON_ERROR_DEPTH:
echo ' - Maximum stack depth exceeded';
break;
case JSON_ERROR_STATE_MISMATCH:
echo ' - Underflow or the modes mismatch';
break;
case JSON_ERROR_CTRL_CHAR:
echo ' - Unexpected control character found';
break;
case JSON_ERROR_SYNTAX:
echo ' - Syntax error, malformed JSON';
break;
case JSON_ERROR_UTF8:
echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
break;
default:
echo ' - Unknown error';
break;
}

Categories