Need to keep backslashes in JSON feed when parsing in PHP - php

here is an example of one of our JSON feeds:
{"wiggins": {
"id": "bkstir-04380-wdr-q",
"alertcolour": "yellow",
"infohvr": "",
"infoclk": "",
"warning": "10",
"warnhvr": "There are 10 files stuck in \\server.domain.co.uk\Country\Dept\Output",
"warnclk": "\\server.domain.co.uk\Country\Dept\Output",
"process": "abc-app-015 Spooler",
"processhvr": "",
"processclk": "http://xyz-abc-001.svr.domain.co.uk/monitors/39.html"
}}
the backslashes are stopping the php from displaying it, if I have a JSON without any backslashes in it then they display fine, however I need the slashes in there as the person displaying the page needs to go to the link. To get it working for now I've also tried stipslashes() but it doesn't work. Can anyone offer any advise? thanks. This is the code parsing the files (as I say, this bit works as long as there are no backslashes):
$path = "../../Admins/VBScript/Monitors/JSON/"; //where JSONs are stored
foreach (glob($path."*.json") as $file){ //loop through each file
$json = file_get_contents($file); //get JSON files
$data = json_decode($json, true); //parse the file
The JSON files come back as valid on sites I've tested them on.

Your JSON is not valid. Backslashes have to be escaped like this:
{"wiggins": {
"id": "bkstir-04380-wdr-q",
"alertcolour": "yellow",
"infohvr": "",
"infoclk": "",
"warning": "10",
"warnhvr": "There are 10 files stuck in \\\\server.domain.co.uk\\Country\\Dept\\Output",
"warnclk": "\\\\server.domain.co.uk\\Country\\Dept\\Output",
"process": "abc-app-015 Spooler",
"processhvr": "",
"processclk": "http://xyz-abc-001.svr.domain.co.uk/monitors/39.html"
}}
According to this question you could use
$json = str_replace('\\', '\\\\', $json);
to fix your JSON.

Your JSON data is not considered valid JSON according to the standards in place. Using JSONLint your data throws parser errors until all slashes are escaped. You can read this standard here: JSON Data Standard The information above is on page 4 and requires forward and backward solidus characters to be escaped. JSON_ENCODE() and JSON_DECODE() will take care of the removal of the escapes as well so your formatting for an HTML link should be valid.

Related

how to handle JSON embedded quotes in title with youtube-data-api-v3

I have been getting JSON decode errors with data returned by YouTube Data API v3, where the returned JSON includes quotes embedded within the title field.
$json = curl_init();
$optArray = array(
CURLOPT_URL => $apiCall,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_SSL_VERIFYHOST => FALSE
);
curl_setopt_array($json, $optArray);
$result = curl_exec($json);
curl_close($json);
Error Message: Syntax error
A recent example includes "videoId": "Q6AYg0oLfC8", where this is returned for the title field: "title": "Trump and His Allies Want You to "Adapt" to the Coronavirus Crisis: A Closer Look".
With the PHP 7 JSON decoder v 1.4.0, this JSON does not parse due to the embedded quotes in the title field.
What is the best practice to handle embedded quotes in title or any other field returned by API JSON responses?
I can upload the JSON returned by YouTube as a file if that helps. (Or can explain how files are attached to Stack Overflow.)
In my experience, I never came across invalid JSON produced by any of the endpoints of YouTube's Data API.
On the other hand, please note that embedding quotes in strings is perfectly legal JSON. That is, if obeying the prescribed syntax: each quotation mark character to be embedded into a JSON string must be escaped, i.e. must be preceded by a single reverse solidus character -- that is \.
Otherwise, this basic feature of JSON is handled seamlessly by json_decode. (Am assuming that you actually are using json_decode.) For example, in case of this simple JSON text:
{"foo":"bar\"baz\"boo"}
json_decode works OK according to this site. Note that in PHP, that JSON text and the call to that function would look like:
$val = json_decode('{"foo":"bar\\"baz\\"boo"}')
For to try helping you further, do post here the relevant piece of PHP code that produces the error mentioned, along with the error message(s) generated.
Update upon OP's posting source code
Upon running the following curl command line at a stock GNU/Linux bash prompt:
$ curl -o Q6AYg0oLfC8.json "https://www.googleapis.com/youtube/v3/videos?key=$YOUTUBE_DATA_APP_KEY&id=Q6AYg0oLfC8&part=contentDetails,id,liveStreamingDetails,player,recordingDetails,snippet,statistics,status,topicDetails"
I did obtained a valid JSON text. The title field looks like shown below:
$ grep Q6AYg0oLfC8.json -ne '"title"' -B4
8- "id": "Q6AYg0oLfC8",
9- "snippet": {
10- "publishedAt": "2020-07-16T01:00:02Z",
11- "channelId": "UCVTyTA7-g9nopHeHbeuvpRA",
12: "title": "Trump and His Allies Want You to \"Adapt\" to the Coronavirus Crisis: A Closer Look",
--
91- ],
92- "categoryId": "23",
93- "liveBroadcastContent": "none",
94- "localized": {
95: "title": "Trump and His Allies Want You to \"Adapt\" to the Coronavirus Crisis: A Closer Look",
These strings are indeed valid.

How to properly store CKEditor HTML input

Im using CKEditor to store HTML input. Its working fine the one way. Data goes into the database exactly as I input it.
However, when I try to retrieve it in JSON, I get all sorts of parsing errors.
Here is a simple string which screws up
<p>This is my text</p>
<span style="font-size:14px">More test</span>
The JSON gets hung up on the double quotes, and the spaces. So I implemented this function in PHP before it gets inserted.
function parseline($string){
$string = str_replace(chr(10), "//n", $string);
$string = str_replace(chr(13), "//n", $string);
$string = str_replace(chr(34), "'", $string);
$string = str_replace("'","\'", $string);
return $string;
}
That line then becomes
<p>This is a test and more content</p>//n<span style=\'font-size:72px\'>
However. This still hangs up the JSON parsing.
How do I correctly store data from CKEditor, and then how to parse it back from the database, so that it can be parsed correctly as JSON??
Ideally I want to store it properly. And then I'll need to reverse parse the //n out to display back in the editor properly. Because right now, if I get valid data, I still get the //n displayed in the editor as actual values.
Ive been on this for 6 hours now. And Im tearing my hair out.
EDIT - Still stuck on this 22 hours later
Here is what is going into the database
<p>qweqweqweqwe</p>
And then Im getting it like this (using Lumen/laravel)
$post = Post::find($id);
return json_encode($post);
Then in Vue Im getting that json
el:'#app',
data : {
post: {}
},
methods: {
getPost: function(id){
var that = this;
$.ajax({
url:'post/'+id,
dataType:'json',
type:'GET'
}).done(function(data){
// Assign the data to Vue
that.post = JSON.parse(data);
}).fail(function(xhr){
});
}
}
This fails, with this exception
Uncaught SyntaxError: Unexpected token
in JSON at position 175
And the json returned is
{"uuid":"0bcb9c59-19da-4dcf-90d6-6dd53adfb449","title":"test","slug":"test","body":"<p>qweqweqweqwe</p>
","created_at":1519529598,"updated_at":1519534639}
So obviously its failing because there is an Enter key after the ending < /p >. But I already tried removing all enter keys and all that before storing. Replacing with new line /n. That works, but then I get //n back, and also things like style="font-size:14px;" from CKeditor, also make it fail, because of the double quotes.
So the issue is. Im storing the data exactly as its entered in the database. Retrieving it properly is just most definitely not working or easy to do at all it seems. At least as valid json.
EDIT 3 - Completeley lost and officially stumped
Im getting this back as json
var data = {
"uuid": "2cd2d954-233a-46d6-8111-29596262d3bc",
"body": "<p>test<\/p>\n",
"cover_img": "https:\/\/static.pexels.com\/photos\/170811\/pexels-photo-170811.jpeg",
"title": "asdf",
"slug": "asdf",
"created_at": 1519536364,
"updated_at": 1519538302
}
If i do
JSON.parse(data);
I consistently get
Uncaught SyntaxError: Unexpected token
in JSON at position 66
Even though if you copy that exact object over to JSONLint.com, its completely valid. Im so stumped. The most stumped I think I have ever been on any issue in my entire career. Which is wierd, because it seems like it would be such an easy bug to find.
Store it directly as HTML in the database. Don't modify, tweak, or otherwise screw with it at all - what's in the database should be exactly what the user submitted. (Stuff like XSS protection, parsing short codes, etc. should be done on display, so you can adjust your algorithms while still having the original HTML to work with.)
Provide it to Vue by running it through json_encode, which will escape it correctly:
$response = ['html' => $html];
return json_encode($response);
(You can also just do json_encode($html), which will return a JS-friendly string instead of a JSON object. Vue'll be happy with that, too.)
The resulting JSON will be:
{"html":"<p>This is my text<\/p>\n\n<span style=\"font-size:14px\">More test<\/span>"}
which Vue will be just fine with when you JSON.parse it.
Assuming a CKEditor instance named editor1, get CKEditor data, construct an object with it, stringify it and send it to database without PHP manipulation (JSON.stringify will take care of escaping characters):
JSON.stringify({'ckdata': editor1.getData()})
Retrieve data from database as text without PHP manipulation and parse it as JSON object:
JSON.parse(databasedata).ckdata;
EDIT: ceejayoz gave a better answer, since data is stored unmodified in database

How do I encode a single qoute while backslash does not escape it in the JSON?

Below this is my Json which is valid. I use this JSON to send notifications on Android and iOS devices using SNS. However,
{
"default": "",
"GCM": "{ \"data\": { \"message\": \"{'user_id':'48491','story_title':'Who is Trumps dangerous best friend?','story_slug':'Who-is-Trumps dangerous best friend?','story_id':'40372','user_full_name':'Gourav Choubey','cover_image':'url','user_profile_photo':'url'}\" } }"
}
When I add an ' (Single Qoute) to the title, such as the JSON below, is still a valid JSON but on the Device side, the JSON decode is unable to read the JSON, due to single qoute on also Story_title, and it's key also starts with a single qoute.
But the Android app is unable to show the single qoutation (') and nothing is shown in the notification.
{
"default": "",
"GCM": "{ \"data\": { \"message\": \"{'user_id':'48491','story_title':'Who is Trump's dangerous best friend?','story_slug':'Who-is-Trumps dangerous best friend?','story_id':'40372','user_full_name':'Gourav Choubey','cover_image':'url','user_profile_photo':'url'}\" } }"
}
I tried HTML encoding, and backslash to escape the single qoute.
However nothing works, without giving an update to the app, how do I make sure the single qoute is correctly sent?
The end device only takes in the string I sent.
Here is my PHP code.
$android_notification_fields = array(
"user_id" => $result->user_id,
"story_title" => addslashes($title),
"story_id" => $result->story_id,
"user_full_name" => addslashes($result->user_full_name),
"cover_image" => $result->cover_image,
'user_profile_photo' => $result->user_profile_photo
);
$push_message = '{ "default": "", "GCM":"{\"data\":{\"message\": \"'.str_replace('"', "'", str_replace('\\','',utf8_encode(json_encode($android_notification_fields)))).'\"}}"}';
print_r($push_message);
$topic_arn = $this->android_topic_arn;
}
I know this is simple, (I do the backend in PHP). I am trying to solve this from a number of days, any help will be really appreciated. I wanna avoid changing anything on the Android App.

json_decode failing

I have the following JSON formatted string:
{
"hooks":[
{
"type":"subscribe",
"id":1331741592.6925,
"email":"JoeX#test-email.com",
"status":"Active",
"custom_fields":"{\"first_name\":\"Joe\",\"last_name\":\"X\"}",
"ip_created":"24.199.200.142",
"list_id":"33",
"list_type":"internal",
"list_name":"Administrator List 2",
"list_optin":false
},
{
"type":"subscribe",
"id":1331741592.7067,
"email":"JaneY#test-email.com",
"status":"Active",
"custom_fields":"{\"first_name\": \"Jane\",\"last_name\":\"Y\"}",
"ip_created":"24.199.200.142",
"list_id":"33",
"list_type":"internal",
"list_name":"Administrator List 2",
"list_optin":false
}
]
}
I want to use the PHP json_decode() function to put it in an associative array.
When I do run the script, debugging shows the value of the new array as null, so I presume the decode is failing. We aren't running PHP 5.3, so I can't use json_last_error(). Here is the code:
$hooks = (the JSON string from above);
$hooksArray = json_decode($hooks, true);
Any ideas why the $hooksArray is coming back null?
Is the JSON string inside your PHP source? Perhaps it's not interpreting the escaped backslashes correctly.
I tried the following experiment in Python for reference: Dumped the JSON data into a multi-line string via the REPL and decode it with json.loads(). It choked on the in-string quotes in the first instance of the custom_fields string. When I examined the multi-line string, all the escapes were gone, leaving me only with the quotes.
When I put the same JSON data in an external file and loaded it, it worked fine.
I put the JSON data in an external file and replaced all '\"' instances with '\\"' and then the first experiment started to work.
Maybe that will work for you too.

Cakephp JSON response with json_encode not working

I'm using ajax function to get the data back for my jquery autocomplete but it seems to not parse the json response and I cannot find why.
I look did console.log for one that is working which is another json response and the other one which is not working and in chrome Console, I can see below. The first one is not working and second one is working.
["17","17","16","20","19","18","23","18","20","18","23","23"]
["25", "24", "25", "24", "24", "23", "21", "23", "22", "21", "22", "22"]
I can see that the second one has red color on numbers and I cannot find out why.
Can someone find out why it's not parsing this JSON?
The second one has a space (or some other character that displays as such) after each comma. If this is how your json_encode() call outputs it, you can run an additional measure to ensure those spaces aren't there before returning it to your AJAX function:
$encoded_text = str_replace(" ","",$encoded_text);
Don't use that if you may have data which has spaces normally. I'm not sure if that is what is causing it to not work, but that is the only difference in the strings you showed us.
You can also use JSONLint to validate your JSON for free.

Categories