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":"\\/\+\\/"}
Related
I've got a problem, I store string in $_COOKIE['restaurant_name'] it stores string for example: "MMM skanu", when I try comparing them, they seem like they're different strings,
if ($_COOKIE['restaurant_name'] == "MMM skanu")
{
// always false
}
but when I for example
try to print it, with echo $_COOKIE['restaurant_name']; I see it's printing the same string "MMM skanu". I tried using strval() function, but it's still the same. How do I parse or convert this cookie to string? I can also see in my google chrome cookies, that restaurant_name = %20MMM%20skanu%20, does it have anything to do with it?
Here I'm decoding any encoding like '%20' using the inbuilt function urldecode. This function decodes encoded characters and turns them into a space charachter for example "what%20" after decoding is "what ".
Using trim I'm removing any extra space for example "%20what" after decoding becomes " what" and trim removes the space there.
$restaurant_name = trim(urldecode($_COOKIE['restaurant_name']));
if($restaurant_name == "MMM skanu"){
// do something
}
I am trying to decode this URL string using PHP's urldecode function:
urldecode("%3CR201810579707%3E%20%3C20180828%3E%20%3C20180912%3E%20%3C1033.00%3E%20%3CY%3E%20%3C0.00%21NA%3E");
This is supposed to output...
<R201810579707> <20180828> <20180912> <1033.00> <Y> <0.00!NA>
...but instead is ouptutting this
<20180828> <20180912> <1033.00> <0.00!NA>
I've tested the string in a php online decoder with great success, but can't seem to do this operation server side. Any ideas?
If you're printing the result on a web page, the angle brackets will be treated as tag delimiters. You can display it literally by calling htmlentities():
echo htmlentities(urldecode("%3CR201810579707%3E%20%3C20180828%3E%20%3C20180912%3E%20%3C1033.00%3E%20%3CY%3E%20%3C0.00%21NA%3E"));
I am trying to parse some json data using json_decode function of php. However, I need to remove certain leading and trailing characters from this long string before decoding. Therefore, I am using preg_match to remove those characters prior to decode. For some reason, preg_match is changing escaping when it encounters following substring (in the middle of the string)
{content: \\\"\\200B\\\"}
After preg_match the above string looks like this:
{content: \\"\200B\\"}
Because of this, json_decode fails.
FYI, the preg_match pattern looks like this:
(?<=remove_these_leading_char)(.*)(?=remove_these_trailing_char)
OK, so here is the additional information based on the questions being asked:
Why triple escaping? fix triple escpaing etc. The answer is that I don't have any control over it. It is not generated by my code.
The original string is not fully json compliant. It has several leading and trailing characters that need to be removed. Therefore I have to use regex. The format of that string is like this:
returnedHTMLdata({json_object},xx);
It looks like this behavior is not limited to preg_match only. Even substr also does this.
It looks like you've got some JSON with padding. To remove the function name and parenthesis, leaving the (unescaped) json object, you can do something like this:
$str = <<<'EOS'
returnedHTMLdata({content: \\\"\\200B\\\", foo: \\\"bar\\\", \"baz\": \\\"fez\\\"},xx);
EOS;
$str = preg_replace('/.+?({.+}).+/','$1', $str);
echo $str;
Output:
{content: \\\"\\200B\\\", foo: \\\"bar\\\", \"baz\": \\\"fez\\\"}
Please note that even if you manage to successfully unescape this string, json_decode requires that keys - e.g. "content" - are enclosed in double quotes, so you will need to modify the JSON string/object before calling that function. Or I guess you could instead use something like the old Services_JSON package to decode it, which I believe does not have that requirement.
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.
I have some weirdly formatted json string which is invalid json, but executes as valid javascript. This means PHP json_decode, will not work.
{
"Devices":{
"Device1":"{ \"Name\"=\>\"AutoTap LDVDS\",\"ID\"=\>\"LDVDSDevice\"}"
}
}
The backslashes are not valid. Is there some way I can escape this string so it can be re-encoded exactly the same as it came in?
Edit I don't care about parsing the messy string at all. It's preventing me from accessing other data. I was doing a simple regex to strip the ugly strings out of the json before parsing it. But now I need to re-encode the result array back into JSON and I want to avoid losing this data. The ugly string should remain exactly the same, as it may be important to some other application that uses this data.
The => comes from ruby object notation in case you are wondering.
Well, it's those weird escaped > that are killing it: \>
I see no reason why you can't str_replace them out of existence safely with a simple:
<?php
$code='{
"Devices":{
"Device1":"{ \"Name\"=\>\"AutoTap LDVDS\",\"ID\"=\>\"LDVDSDevice\"}"
}
}';
$code=str_replace('\\>','>',$code);
var_export(json_decode($code));
But then, you know the domain of your data.
And you should apply a grain of salt before applying that blindly to all your inputs.
You could run stripslashes on it, and then pass that sring into json_decode.