Can I decode JSON containing PHP code? - php

Is it possible to have a JSON string containing PHP Code, and to have this string decoded?
For example, this works as it should:
$array = ["page", "is-home", $_SERVER["REQUEST_URI"] == "/"];
var_export($array);
// array (
// 0 => 'page',
// 1 => 'is-home',
// 2 => false,
// )
This, does not work:
$json = '["page", "is-home", $_SERVER["REQUEST_URI"] == "/"]';
$array = json_decode($json); // returns NULL
echo json_last_error_msg(); // Syntax error
The second example will only work if $_SERVER["REQUEST_URI"] == "/" is removed from the json string.
Is there a way to parse this string using json_decode, and if not, are there alternative methods to accomplish this?
Many thanks!
UPDATE
The $_SERVER["REQUEST_URI"] == "/" has to be parsed. I am trying to extend Blade Templating so that I can implement parsed functions such as this:
#add-request('page', 'is-home', $_SERVER["REQUEST_URI"] == '/')
UPDATE #2
To try to simplify the matter, I need to turn a string into an object.
$str = '["page", "is-home", $_SERVER["REQUEST_URI"] == "/"]'; // this is obtained by parsing the top blade extension (not important how)
From the string I need the following array:
$array = ["page", "is-home", true / false ]
Keep in mind that the original string can contain theoretically any PHP object for one of the JSON values.

I think you're on the right track, but instead of trying to "simulate" a decode by putting single-quotes, why not (for your proof of concept) first ENCODE, then 'echo' / 'print' the value that it returns, and then DECODE to see what it returns.

Why don't you use json_encode() to obtain json string??
// create json string by json_encode() from array
$json = json_encode([
"page",
"is-home",
$_SERVER["REQUEST_URI"] == "/"
]);
// decode the encoded string with no error, of course ....
$array = json_decode($json);

As you can clearly see in the output, your first array does not contain any PHP at all.
$array = ["page", "is-home", $_SERVER["REQUEST_URI"] == "/"];
automatically fills $array[2] with the boolean false, not with PHP code.
So, let's assume you can't do such a calculation on the client (in fact, you can do this calculation in javascript as well). So you would have to send it to the server as a json string (properly encoded), decode it, eval it, and post the result back into the array.
$json = '["page", "is-home", "$_SERVER[\"REQUEST_URI\"] == \"/\""]';
$array = json_decode($json);
$array[2]=eval($array[2]);
But please don't do this! It is a big security hole.
Instead, feel free to ask a new question as to how you can do this calculation in javascript as well.

For your case you could do:
$is_home = $_SERVER["REQUEST_URI"] == "/";
$json = '["page", "is-home", '. $is_home .']';
$array = json_decode($json);

That's because you are using a variable in your string which is not parsed. In addition, $_SERVER["REQUEST_URI"] == "/" returns false. Boolean false will be converted to an empty string if it is concatenated to a string.
You should rewrite your code to something like this:
// Is the request URI equal to "/"?
$reqUriTest = ($_SERVER["REQUEST_URI"] == "/");
// If boolean false is converted to a string, it will become an empty string.
// So we need to explicitly use values "true" or "false".
$reqUriStr = ($reqUriTest ? "true" : "false");
// Now we can insert $reqUriStr into the JSON string.
$json = '["page", "is-home", '.$reqUriStr.']';
$array = json_decode($json);

Related

Can't decode JSON from file in PHP

I'm having troubles with json_decode in PHP:
I have this on file:
{1: ['oi','oi'], 2: ['foo','bar']}
And this is my php code:
<?php
$string = file_get_contents("quizen.json"); // the file
$json = json_decode($string);
echo $json[1][0]
?>
But the echo returns anything, I used var_dump, and I get NULL!
What's the problem?
The issue is that your file is not valid JSON since it uses single quotes for strings and has integers as object keys:
{1: ['oi','oi'], 2: ['foo','bar']}
Also, since the JSON is an object, you should decode it to an associative array using json_decode($string, true).
According to the JSON spec:
A value can be a string in double quotes, or a number, or true or false or null, or an object or an array.
Also, the object keys need to be strings.
If you change the single quotes to double quotes and edit your PHP's decode_json call to decode to an associative array, it should work. For example:
JSON:
{"1": ["oi","oi"], "2": ["foo","bar"]}
PHP:
<?php
$string = file_get_contents("quizen.json"); // the file
$json = json_decode($string, true); // set to true for associative array
echo $json["1"][0];
?>

How to check json encoded string?

I found that many of you use a function like this...
function isJson($string) {
json_decode($string);
return (json_last_error() == JSON_ERROR_NONE);
}
(from Fastest way to check if a string is JSON in PHP?)
Many of json encoded string contain these characters { : , "
If i check the string that contain these characters it may return true.
example:
$var = '{"1":"a2","a2":{"1":"a2.2","2":"a2.2"}}';
var_dump(isJson($var)) // true;
But when i check the string that is just a number, it return true too.
example:
$phone = '021234567';
var_dump(isJson($phone)); // true
I don't think the string '021234567' is json encoded and it should return false.
Let see more example for more clear question.
$var1 = '021234567'; // this is string. not integer. NOT json encoded.
$var2 = '"021234567"'; // this is json encoded.
$var3 = 021234567; // this is integer. NOT json encoded.
$var4 = 'bla bla'; // this is string. NOT json encoded.
$var5 = '{"1":"a2","a2":{"1":"a2.2","2":"a2.2"}}'; // this is json encoded.
var_dump(isJson($var1));
var_dump(isJson($var2));
var_dump(isJson($var3));
var_dump(isJson($var4));
var_dump(isJson($var5));
the results are:
true
true
true
false
true
But the expected results are:
false
true
false
false
true
The question is. How to check the string that is valid json encoded?
More example 2
If 021234567 is an integer. when i use json_encode it returns integer and have nothing to do with it again when use json_decode
$var = 021234567;
echo $var; // 4536695
echo json_encode($var); // 4536695
echo json_decode(4536695); // 4536695
echo json_decode($var); // 4536695
$var = 21234567;
echo $var; // 21234567
echo json_encode($var); // 21234567
echo json_decode(4536695); // 21234567
echo json_decode($var); // 21234567
so, the integer value should return false when i check json encoded string with isJson function. but it is not.
If 021234567 is string. when i use json_encode i should got "021234567" (with double quote). if this string has no double quote, it should not be json encoded.
$var = '021234567';
echo $var; // 021234567
echo json_encode($var); // "021234567"
echo json_decode('"021234567"'); // 021234567
echo json_decode($var); // 21234567
// example if string is text with double quote in it.
$var = 'i"m sam';
echo $var; // i"m sam
echo json_encode($var); // "i\"m sam"
echo json_decode('"i\"m sam"'); // i"m sam
echo json_decode($var); // null
As you see. the simple string with json encoded should contain at least double quote character at open and close of that string.
Please help me how to check that string is valid json encoded.
I think the valid json encoded string should at least have double quote " or curly bracket {} at the open and close of that string.
I don't know how to check that or don't know how to preg_match that.
From PHP Documentation:
PHP implements a superset of JSON - it will also encode and decode scalar types and NULL. The JSON standard only supports these values when they are nested inside an array or an object.
So, the reason leading zeros make this check pass is that json_decode just strips them during parsing without giving any errors. For example:
echo json_decode('0123');
will just display 123.

PHP preg_split and replace

I currently have this code running. It is splitting the variable $json where there are },{ but it also removes these characters, but really I need the trailing and leading brackets for the json_decode function to work. I have created a work around, but was wondering if there is a more elegant solution?
<?php
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5},{"a":1,"b":2,"c":3,"d":4,"e":5}';
$individuals = preg_split('/},{/',$json);
$loop_count =1;
foreach($individuals as $object){
if($loop_count == 1){$object .='}';}
else{$object ="{".$object;}
print_r(json_decode($object));
echo '<br />';
$loop_count++;
}
?>
EDIT:
The $json variable is actually retrieved as a json object. An proper example would be
[{"id":"foo","row":1,"col":1,"height":4,"width":5},{"id":"bar","row":2,"col":3,"height":4,"width":5}]
As you (presumably) already know, the string you have to start with isn't valid json because of the comma and the two objects; it's basically two json strings with a comma between them.
You're trying to solve this by splitting them, but there's a much easier way to fix this:
The work-around is simply to turn the string into valid JSON by wrapping it in square brackets:
$json = '[' . $json . ']';
Voila. The string is now valid json, and will be parsed successfully with a single call to json_decode().
Hope that helps.
You can always add them again.
Try this:
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5},{"a":1,"b":2,"c":3,"d":4,"e":5}';
$individuals = preg_split('/},{/',$json);
foreach($individuals as $key=>$val)
$individuals[$key] = '{'.$val.'}';

Parse JavaScript from remote server using curl

I need to grab a json-string from this page: https://retracted.com
If you view the source, I json-string starts after var mycarousel_itemList =. I need to parse this string as a correct json-array in my php-script.
How can this be done?
EDIT: I've managed to pull this off using explode, but the method is ugly as heck. Is there no build-in function to translate this json-string to a array?
To clarify: I want the string I grab (which is correct json) to be converted into a php-array.
The JSON in the script block is invalid and needs to be massaged a bit before it can be used in PHP's native json_decode function. Assuming you have already extracted the JSON string from the markup (make sure you exclude the semicolon at the end):
$json = <<< JSON
[ { address: 'Arnegårdsveien 32', … } ]
JSON;
var_dump(
json_decode(
str_replace(
array(
'address:',
'thumb:',
'description:',
'price:',
'id:',
'size:',
'url:',
'\''
),
array(
'"address":',
'"thumb":',
'"description":',
'"price":',
'"id":',
'"size":',
'"url":',
'"'
),
$json
)
,
true
)
);
This will then give an array of arrays of the JSON data (demo).
In other words, the properties have to be double quoted and the values need to be in double quotes as well. If you want an array of stdClass objects instead for the "{}" parts, remove the true.
You can do this either with str_replace as shown above or with a regular expression:
preg_match('
(.+var mycarousel_itemList = ([\[].+);.+function?)smU',
file_get_contents('http://bolig…'),
$match
);
$json = preg_replace(
array('( ([a-z]+)\:)sm', '((\'))'),
array('"$1":', '"'),
$match[1]
);
var_dump(json_decode($json, true));
The above code will fetch the URL, extract the JSON, fix it and convert to PHP (demo).
Once you have your json data, you can use json_decode (PHP >= 5.2) to convert it into a PHP object or array

JSON string outputs a float value

I am parsing a JSON response (twitter api - cursor value) and what should be a string value seems to be a double value when I output it with PHP.
Any idea how I get the real string value?
The curser value is too large for 32bit PHP installs to handle with json_decode. Someone sent me preg_replace( '/next_cursor":(\d+)/', 'next_cursor":"\1"', $json );. Running that before json_decode will convert the json int to a string before conversion.
Update: Twitter now provides next_cursor_str values that are strings instead of integers so using preg_replace is no longer needed.
To convert a float (or any type of variable) to a string, you can use one of these:
$value = 5.234;
// Using type casting
$str_value = (string)$value;
// Using strval()
$str_value = strval($value);
// Using concatenation to a string
$str_value = $value . '';
// Using sprintf
$str_value = sprintf("%s", $value);
// Using setType
setType($value, 'string');
$str_value = $value;

Categories