Why json_decode doesn't work for me? - php

I'm a little confused here. if I pass a variable to json_decode, it doesn't work:
$stringJSON = $_GET['jsonstring'];
echo $stringJSON;
$stringObject = json_decode($stringJSON);
var_export($stringObject);
The first echo correctly shows me the JSON string I passed, e.g.
{\"Items\":[{\"Name\":\"name\",\"Description\":\"\"],\"Name\":\"Christmas\"}
The second echo shows NULL.
So I grab the string from the first echo and write the following code:
$stringObject = json_decode("{\"Items\":[{\"Name\":\"name\",\"Description\":\"\"],\"Name\":\"Christmas\"}");
var_export ($stringObject);
And what do you say, it shows me the correctly decoded array. The string is absolutely the same, I even kept the escape characters. Or maybe they are the problem?

Looks like your server has magic_quotes_gpc enabled. Either disable it or run $stringJSON through stripslashes() before using it.
$stringJSON = get_magic_quotes_gpc() ?
stripslashes($_GET['jsonstring']) : $_GET['jsonstring'];

This
[{\"Name\":\"name\",\"Description\":\"\"]
needs to be
[{\"Name\":\"name\",\"Description\":\"\"}]
You are missing the closing }

If it shows you a string with slashes in it when you echo it, that means the string has slashes in it. That's not a valid JSON string, the slashes don't belong there. If you paste that string into PHP, the slashes are evaluated by PHP. The string literal "\"" in PHP source code evaluates to the string ", so the slashes are effectively removed and you are decoding a valid JSON string.
I suspect you have Magic Quotes on which are inserting the slashes into GET values, turn them off.

This is a quoting problem: Try the following
$stringObject = json_decode("{\"Items\":[{\"Name\":\"name\",\"Description\":\"\"],\"Name\":\"Christmas\"}");
echo $stringObject;
var_export ($stringObject);
as you see, the $stringObject has no quotes (but the one coming from $_GET has them)
so you might need
$stringJSON = $_GET['jsonstring'];
$stringObject = json_decode(stripslashes($stringJSON));
var_export($stringObject);

run json_decode twice.
$str = json_decode($jsonData,true);
$str = json_decode($str,true);
It may help someone.

json_encode($str, JSON_UNESCAPED_SLASHES);
it may help you.

Related

Regex how to escape double quotes if needed

I need to convert all big integers to strings in my response json. Currently my regex look like this
preg_replace(
'/:\s*(-?\d{16,})/',
': "$1"',
$content
);
But problem with such regex is that if my response contains another json string then bigints inside it will be wrapped in string too, but without escaping. Is there any way to escape appended quotes in such case? Or maybe fix incorrect json with another regex?
Example
{"example_bigint": 3330922503411457761}
will be converted to
{"example_bigint": "3330922503411457761"}
but
{"example_json" : "{\"example_bigint\": 3330922503411457761}"}
will be converted to
{"example_json" : "{\"example_bigint\": "3330922503411457761"}"}
when expected output is
{"example_json" : "{\"example_bigint\": \"3330922503411457761\"}"}
There is a flag in the json_decode function:
$myJson = json_decode($jsonString, flags: JSON_BIGINT_AS_STRING);

PHP json_decode a json_encoded string

I don't really get the following...
// array to encode
$a = ['regex' => '\/\+\/'];
// decoding an encoded array works
print_r(json_decode(json_encode($a), true));
// encoded array
echo json_encode($a);
// trying to decode the before encoded string doesn't work
print_r(json_decode('{"regex":"\\\/\\+\\\/"}', true));
echo json_last_error_msg();
The last error message says Syntax error. Shouldn't I be able to easily decode a simple encoded string?
I know that the problem is in the backslashes but I won't want to do any magic string replacement or regex to get the decoding working. Just want to understand where goes what wrong and what's a best practice for this kind of situations?
I'm using PHP version 5.5.9
Found something thanks to that answer : https://stackoverflow.com/a/10929508/1685538
If instead of taking the string outputted by echo, you use var_export(json_encode($a)); (documentation), it gives you {"regex":"\\\\\\/\\\\+\\\\\\/"}
print_r(json_decode('{"regex":"\\\\\\/\\\\+\\\\\\/"}', true)); gives the expected result :
Array
(
[regex] => \/\+\/
)
with no errors.
The problem is that using backslashes in PHP code string literals is subject to PHP's backslash escaping rules. You need to additionally escape the backslashes so they are preserved inside the PHP string:
print_r(json_decode('{"regex":"\\\\\\/\\\\+\\\\\\/"}', true));
Contrast with:
echo '{"regex":"\\\/\\+\\\/"}';
// {"regex":"\\/\+\\/"}

json_decode return "NULL" help me

I get json string:
$response = '{"retcode":"0","retmsg":"OK","cre_id_enc":"","cre_type":"","fee_type":"1","listid":"1221085301201410240000001024","out_trade_no":"201410246763831","partner":"1221085301","pay_fee":"0","sign":"PTamau\x2BjkynA00cASKJ6Nd3QwFSBP44TKSqmmdCd\x2F\x2B0o8ViSt3fp5vQr0Fc73U42NhtImfnHzbynoUjURiNLW5O4hI61xkG\x2F97JRPRE0nHuvtAumqXfbVCsLveugE52HRZsJvm3EG7pL6GlhYf8ng6qxiUrDyn89PFVZ04Wd8Gk\x3D","total_fee":"1000000","unfreeze_fee":"1000000","user_name_enc":""}';
I use json_decode to convert this string to array,but it return "NULL".
I found "sign":"PTamau\x2BjkynA00cASKJ6Nd3QwFSBP44TKSqmmdCd\x2F\x2B0o8ViSt3fp5vQr0Fc73U42NhtImfnHzbynoUjURiNLW5O4hI61xkG\x2F97JRPRE0nHuvtAumqXfbVCsLveugE52HRZsJvm3EG7pL6GlhYf8ng6qxiUrDyn89PFVZ04Wd8Gk\x3D","total_fee":"1000000" can't use json_decode.
it contains ASCII code like '\x2F' , '\x2B', '\x3D'.
so I try to convert to utf8, like this $response = iconv('ASCII', 'UTF-8//IGNORE', $response);.
it's no useful.the response string still contains '\x2F' , '\x2B', '\x3D' and json_decode still return NULL.
someone can help me and forgive me my poor English!
Thank you!
According to an answer on a very similar question, you need to escape the backslashes:
$json = str_replace( '\x', '\\\\x', $response );
and then pass $json to json_decode
The issue is the single quotes.
print_r('\x2F');
\x2F
print_r("\x2F");
/
Single quotes will not interpret the backslash sequence, which leaves you with malformed JSON which only allows \\ and \", AFAIK. If you already have the single-backslash string, do what Vasilis says.

How to json_encode without escaping slashes?

I'm encoding it like so..
json_encode($array_list, JSON_UNESCAPED_SLASHES)
Ex: \n turns into \\n, \r\n turns into \\r\\n
But, it's still escaping the slashes! What's wrong and how to fix it? Thanks.
I think it is because of single and double quotes, see the examples
$arr = array("\n\r");
echo json_encode($arr,JSON_UNESCAPED_SLASHES); // ["\n\r"]
$arr = array('\n\r');
echo json_encode($arr,JSON_UNESCAPED_SLASHES); //["\\n\\r"]
working example http://codepad.viper-7.com/LvWMhq
If it is a concern when doing any MySQL queries then you can use it like this:
mysql_real_escape_string(json_encode($array))
No need to escape anything in the $array itself before this point, just let mysql_real_escape_string escape the json_encoded string.

str_replace doesn't seems to work with the implode function

After imploding an array:
$in_list = "'".implode("','",$array)."'";
$in_list content is :
'Robert','Emmanuel','José','Alexander'
Now when i try to replace the word José by another string,
str_replace("José","J",$in_list);
It doesn't get the new value, José is still there. Am i missing something? thanx in advance.
How exactly do you try to replace the string?
When trying it this way:
$in_list = str_replace("José","J",$in_list);
echo $in_list;
everything should work fine.
Remember, the function is returning a value. So it returns a new string.
This should work. It depends on your array.
$str = array('Robert','Emmanuel','José','Alexander');
$str = implode(",", $str);
print str_replace('José', 'J', $str);
I'm not sure what's going on, It seems to work for me. What version of PHP are you using?
$in_list = "'".implode("','", array('Robert', 'Emmanuel', 'José', 'Alexander'))."'";
$replaced = str_replace("José", "J", $in_list);
//prints 'Robert','Emmanuel','J','Alexander'
echo $replaced;
See: http://codepad.viper-7.com/24qutm
try $in_list = html_entity_decode((str_replace(htmlentities("José"),"J",htmlentities($in_list));
Have you tried on a word without accents? I would say you have a character set mismatch, for example 'José' in $in_list is in latin1 character set and your PHP source file in UTF8.
If this is the case, you should first convert either your PHP file or the variable to the character set you want to work with.
Spontaneous guess: Those two strings are not the same. I suppose one "José" is a string hardcoded in your source code and the other is received from the database or the browser or so. If the encoding of the two strings is not the same, PHP won't identify them as identical and not replace the character. Make sure your source code file is saved in the same encoding as the data you're working on, preferably both being UTF-8.
This worked for me, but it doesn't look like I'm doing anything notably different from you?
$array = array('Robert', 'Emmanuel', 'José', 'Alexander');
$in_list = "'".implode("','",$array)."'";
echo $in_list.PHP_EOL;
echo str_replace("José","J",$in_list).PHP_EOL;
Output:
'Robert','Emmanuel','José','Alexander'
'Robert','Emmanuel','J','Alexander'
Keep in mind that str_replace will not perform the replacement on $in_list itself, but rather return a string containing the replacement.
Hope this helps!

Categories