How do I json_decode string with special chars (" \\ " ) - php

I have a problem with encoding and decoding json data. In js I send query with data type 'json', it looks like this:
{\"front\":{\"0\":{\"type\":\"text\",\"width\":\"55px\",\"height\":\"27px\",\"top\":\"151px\",\"left\":\"86px\",\"zIndex\":\"1\",\"svg\":\"<svg width=\\\"54.9375\\\" height=\\\"27.09375\\\" viewBox=\\\"0 0 54.9375 27.09375\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" xmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\"><g id=\\\"0.7882792934370437\\\"><text fill=\\\"#FF0000\\\" stroke=\\\"none\\\" stroke-width=\\\"0\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\" x=\\\"\\\" y=\\\"\\\" text-anchor=\\\"start\\\" font-size=\\\"24px\\\" font-family=\\\"arial\\\" data-textcurve=\\\"1\\\" data-itemzoom=\\\"1 1\\\" data-textspacing=\\\"0\\\"><textPath xmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\" xlink:href=\\\"http://138.68.62.219/Buy-Hanes-T-shirt-PC61LS#textPath-item-0\\\"><tspan dy=\\\"0\\\">Hello</tspan></textPath></text></g><defs><path id=\\\"textPath-item-0\\\" d=\\\"M 0.125 22.117808976867764 A 3093.9720937064453 3093.9720937064453 0 0 1 54.124314613414626 22.117808976867764\\\"></path></defs></svg>\",\"rotate\":0,\"text\":\"Hello\",\"color\":\"#FF0000\",\"fontFamily\":\"arial\",\"align\":\"center\",\"outlineC\":\"none\",\"outlineW\":0}}
Then I save it to cell in MySQL, it looks like this:
{\\"front\\":{\\"0\\":{\\"type\\":\\"text\\",\\"width\\":\\"55px\\",\\"height\\":\\"27px\\",\\"top\\":\\"151px\\",\\"left\\":\\"86px\\",\\"zIndex\\":\\"1\\",\\"svg\\":\\"<svg width=\\\\\\"54.9375\\\\\\" height=\\\\\\"27.09375\\\\\\" viewBox=\\\\\\"0 0 54.9375 27.09375\\\\\\" xmlns=\\\\\\"http:\/\/www.w3.org\/2000\/svg\\\\\\" xmlns:xlink=\\\\\\"http:\/\/www.w3.org\/1999\/xlink\\\\\\"><g id=\\\\\\"0.7882792934370437\\\\\\"><text fill=\\\\\\"#FF0000\\\\\\" stroke=\\\\\\"none\\\\\\" stroke-width=\\\\\\"0\\\\\\" stroke-linecap=\\\\\\"round\\\\\\" stroke-linejoin=\\\\\\"round\\\\\\" x=\\\\\\"\\\\\\" y=\\\\\\"\\\\\\" text-anchor=\\\\\\"start\\\\\\" font-size=\\\\\\"24px\\\\\\" font-family=\\\\\\"arial\\\\\\" data-textcurve=\\\\\\"1\\\\\\" data-itemzoom=\\\\\\"1 1\\\\\\" data-textspacing=\\\\\\"0\\\\\\"><textPath xmlns:xlink=\\\\\\"http:\/\/www.w3.org\/1999\/xlink\\\\\\" xlink:href=\\\\\\"http:\/\/138.68.62.219\/Buy-Hanes-T-shirt-PC61LS#textPath-item-0\\\\\\"><tspan dy=\\\\\\"0\\\\\\">Hello<\/tspan><\/textPath><\/text><\/g><defs><path id=\\\\\\"textPath-item-0\\\\\\" d=\\\\\\"M 0.125 22.117808976867764 A 3093.9720937064453 3093.9720937064453 0 0 1 54.124314613414626 22.117808976867764\\\\\\"><\/path><\/defs><\/svg>\\",\\"rotate\\":0,\\"text\\":\\"Hello\\",\\"color\\":\\"#FF0000\\",\\"fontFamily\\":\\"arial\\",\\"align\\":\\"center\\",\\"outlineC\\":\\"none\\",\\"outlineW\\":0}}
When I read with php this data that's what I see ( $tmp=$products[0]['design_file']; print_r($tmp);) :
"{\\"front\\":{\\"0\\":{\\"type\\":\\"text\\",\\"width\\":\\"55px\\",\\"height\\":\\"27px\\",\\"top\\":\\"151px\\",\\"left\\":\\"86px\\",\\"zIndex\\":\\"1\\",\\"svg\\":\\"<svg width=\\\\\\"54.9375\\\\\\" height=\\\\\\"27.09375\\\\\\" viewBox=\\\\\\"0 0 54.9375 27.09375\\\\\\" xmlns=\\\\\\"http:\/\/www.w3.org\/2000\/svg\\\\\\" xmlns:xlink=\\\\\\"http:\/\/www.w3.org\/1999\/xlink\\\\\\"><g id=\\\\\\"0.7882792934370437\\\\\\"><text fill=\\\\\\"#FF0000\\\\\\" stroke=\\\\\\"none\\\\\\" stroke-width=\\\\\\"0\\\\\\" stroke-linecap=\\\\\\"round\\\\\\" stroke-linejoin=\\\\\\"round\\\\\\" x=\\\\\\"\\\\\\" y=\\\\\\"\\\\\\" text-anchor=\\\\\\"start\\\\\\" font-size=\\\\\\"24px\\\\\\" font-family=\\\\\\"arial\\\\\\" data-textcurve=\\\\\\"1\\\\\\" data-itemzoom=\\\\\\"1 1\\\\\\" data-textspacing=\\\\\\"0\\\\\\"><textPath xmlns:xlink=\\\\\\"http:\/\/www.w3.org\/1999\/xlink\\\\\\" xlink:href=\\\\\\"http:\/\/138.68.62.219\/Buy-Hanes-T-shirt-PC61LS#textPath-item-0\\\\\\"><tspan dy=\\\\\\"0\\\\\\">Hello<\/tspan><\/textPath><\/text><\/g><defs><path id=\\\\\\"textPath-item-0\\\\\\" d=\\\\\\"M 0.125 22.117808976867764 A 3093.9720937064453 3093.9720937064453 0 0 1 54.124314613414626 22.117808976867764\\\\\\"><\/path><\/defs><\/svg>\\",\\"rotate\\":0,\\"text\\":\\"Hello\\",\\"color\\":\\"#FF0000\\",\\"fontFamily\\":\\"arial\\",\\"align\\":\\"center\\",\\"outlineC\\":\\"none\\",\\"outlineW\\":0}}
If I do this:
$tmp=$products[0]['design_file'];
$info=json_decode($tmp);
print_r($info);
It gives me Null.
How can I get my array back from that mess?
Javascript sending:
jQuery(document).triggerHandler( "before.addtocart.design", datas);
var finaldata=JSON.stringify(datas);
jQuery.ajax({
url: 'index.php?route=checkout/cart/add', //URL TO CONTROL FUNCTION add()
type: 'post',
data: 'product_id=' + product_id + '&quantity=' + q+"&option['options']="+finaldata,
Read in Php
if (isset($this->request->post['option'])) {
$option = array_filter($this->request->post['option']);
Pass to view
$data['products'][] = array(
'design_file'=>$product['design_file'],
...
$tmp=$products[0]['design_file'];

You might be storing malformed JSON data. Take a look at these pages (some useful resources right from PHP docs):
http://php.net/manual/en/function.json-encode.php
http://php.net/manual/en/json.constants.php
PS.: The second link is related to the options parameter used in json_encode. You might compose those values the way you want, just like the example below:
$obj = [
"prop1" => 123,
"prop2" => [
"prop2.1" => "Value A",
"prop2.2" => [1, 2, 3, 4, 5]
]
];
$jsonContent = json_encode($obj, JSON_PRETTY_PRINT | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
By the way, you still can send your JavaScript objects to the server using a contentType: 'application/json' setting in $.ajax function call. That will enable you to handle request data from that HTTP request as a PHP object, as it really should be.
Use PHP to serialize your JSON content in order to store it in database instead of bypassing the string directly from the request attributes.

Something is really messed up here. First, your initial JSON is not valid. Somehow it is already has extra slashes.
Check here: Issue with JSON.stringify adding a extra \ and "" to my Json object.
Maybe here: JSON.stringify escaping without need
Also there is missing } in the very end of JSON string (it should be }}} three closing brackets).
Secondly, I guess before you inserted it in database you escaped it (so thats how you got even more slashes) and you did htmlspecialchars(). Considering this, thats how you can parse it in object.
$info = json_decode(stripslashes(htmlspecialchars_decode($tmp.'}')));

Related

Read POST data in AJAX call

I have some Session values that I am constantly changing via Ajax calls. I can't seem to get a handle on the POST data to process it and set the values.
What I am passing to it here is an array of strings like is shown in my code below.
Here is where AJAX calls:
var sessionValues = [];
str = {"PID": "1", "Level": "Main", "MenuName": "Kitchen", "State": "CHECKED"}
sessionValues.push(str);
var postObj = {"sessionData": sessionValues};
$.ajax({
type: 'POST',
data: {'data': postObj},
url: 'setSession.asp'
}).done(function(response){
console.log(response);
})
I have this working fine in a PHP version of the program but my ASP version is not grabbing the data. Here is my PHP ver and the ASP ver as best as I could convert it.
<-- php setSession.php works fine -->
$data = $_POST['data'];
foreach ($data['sessionData'] as $key => $value) {
$projectProduct = "1";
$level = $value["Level"];
$menuName = $value["MenuName"];
$state = $value["State"];
$_SESSION['PID:'.$projectProduct][$level][$menuName]['menu_state'] = $state;
echo "[PID:".$projectProduct."][".$level."][".$menuName."][".$state."]<br>";
}
0 =>>>>> Array<br>[PID:1][Main][Kitchen][CHECKED]
Here I want to do the same thing in ASP
' setSession.asp
data = Request.Form("data")
For Each part In data("sessionData")
projectProduct = part("PID")
level = part("Level")
menuName = part("MenuName")
state = part("State")
Session("PID:" & projectProduct).Item(level).Item(menuName).Remove("menu_state")
Session("PID:" & projectProduct).Item(level).Item(menuName).Add "menu_state", state
response.write("[PID:" & projectProduct&"]["&level&"]["&menuName&"]["&state&"]<br>")
Next
outputs blank
It looks like it never has any data but doesn't throw any errors. Am I reading the POST object correctly?
[edit]
Here is the RAW POST data captured from Fiddler:
data%5BsessionData%5D%5B0%5D%5BPID%5D=1&data%5BsessionData%5D%5B0%5D%5BLevel%5D=Main&data%5BsessionData%5D%5B0%5D%5BMenuName%5D=Kitchen&data%5BsessionData%5D%5B0%5D%5BState%5D=CHECKED
here I used a URL Decode on that string-
data[sessionData][0][PID]=1&data[sessionData][0][Level]=Main Level Plan&data[sessionData][0][MenuName]=Kitchen&data[sessionData][0][State]=CHECKED
This looks like I should be able to loop through the strings now by using
For Each part In Request.Form("data[sessionData]")
but nothing happens. I added a simple loop to look at the request.form and here is what it is seeing:
for each x in Request.Form
Response.Write(x)
Next
' outputs -> data[sessionData][0][PID]data[sessionData][0][Level]data[sessionData][0][MenuName]data[sessionData][0][State]
I guess what this comes down to is just reading through and processing that string correctly, or multiple if more than one is sent. Correct?
The RAW output definitely helps work out what is going on.
What is happening is jQuery is translating the JSON structure into HTTP POST parameters but during the process, it creates some overly complex key names.
If you break down the key value pairs you have something like
data[sessionData][0][PID]=1
data[sessionData][0][Level]=Main Level Plan
data[sessionData][0][MenuName]=Kitchen
data[sessionData][0][State]=CHECKED
As far as Classic ASP is concerned the this is just a collection of string key and value pairs and nothing more.
The correct approach to work out what these keys are is to do what you have done in the question, but with some minor alternations.
For Each x In Request.Form
Response.Write(x) & "=" & Request.Form(x) & "<br />"
Next
Which when outputted as HTML will look similar to the break down shown above.
Armed with the knowledge of what the keys are you should be able to reference them directly from the Request.Form() collection.
Dim pid: pid = Request.Form("data[sessionData][0][PID]")
Response.Write pid
Output:
1

How to parse URL when using the pager plugin with AJAX

I am trying to use the tablesorter pager plugin with AJAX but run into som problemes (or limitations) when trying to handle the AJAX request in my php backend.
If eg. the table is set up with a default sorting of
sortList: [ [0,1], [1,0] ]
I will get a URL like this on my AJAX request:
page=0&size=50&filter=fcol[6]=batteri&sort=col[0]=1&col[1]=0
In my php back end I do a
$cur_sort = $_GET['sort']
and get
col[0]=1
So the last part is missing - I guess since it contains a & char.
How do I get the entire sort string?
That said how is the string col[0]=1&col[1]=0 best parsed? I need to extract the info that col 0 is to be sorter DESC and col 1 ASC.
You can try this;
parse_str($_SERVER['QUERY_STRING'],$data);
It will parse the url to an array;
Also; you should use empty [] instead of [1] and [0]
See more here: parse_str()
Example:
$str = "page=0&size=50&filter=fcol[6]=batteri&sort=col[0]=1&col[1]=0";
parse_str($str, $output);
echo $output['page']; // echo 0
And to answer your question; it is correct; is echoing col[0]=1 because you are dividing with & see here:
&sort=col[0]=1 & col[1]=0;
An advice; use more names, instead.
You could use
&sort[]=1&sort[]=0;
UPDATE:
To access the last one; you should do, simply;
$_GET['col'][1];
If you want to access, the last number in
$_GET['sort'];
You can do this;
$explode = explode('=',$_GET['sort']);
$end = end($explode);
echo $end; //it will outout 1
If you print your entire query_String, it will print this;
Array
(
[page] => 0
[size] => 50
[filter] => fcol[6]=batteri
[sort] => col[0]=1
[col] => Array
(
[1] => 0
)
)
I'm not sure how the ajaxUrl option is being used, but the output shared in the question doesn't look right.
I really have no idea how the string in the question is showing this format:
&sort=col[0]=1&col[1]=0 (where did sort= come from?)
&filter=fcol[6]=batteri (where did filter= come from?)
If you look at how you can manipulate the ajaxUrl option, you will see this example:
ajaxUrl: "http://mydatabase.com?page={page}&size={size}&{sortList:col}&{filterList:fcol}"
So say you have the following settings:
page = 2
size = 10
sortList is set to [[0,1],[3,0]] (1st column descending sort, 4th column ascending sort)
filters is set as ['','','fred']
The resulting url passed to the server will look like this:
http://mydatabase.com?page=2&size=10&col[0]=1&col[3]=0&fcol[2]=fred
The col part of the {sortList:col} placeholder sets the sorted column name passed to the URL & the fcol part of {filterList:fcol} placeholder sets the filter for the set column. So those are not fixed names.
If the above method for using the ajaxUrl string doesn't suit your needs, you can leave those settings out of the ajaxUrl and instead use the customAjaxUrl option to modify the URL as desired. Here is a simple example (I know this is not a conventional method):
ajaxUrl: "http://mydatabase.com?page={page}&size={size}",
// modify the url after all processing has been applied
customAjaxUrl: function(table, url) {
var config = table.config,
// convert [[0,1],[3,0]] into "0-1-3-0"
sort = [].concat.apply( [], config.sortList ).join('-'),
// convert [ '', '', 'fred' ] into "--fred"
filter = config.lastSearch.join('-');
// send the server the current page
return url += '&sort=' + sort + '&filter=' + filter
}
With the same settings, the resulting URL will now look like this:
http://mydatabase.com?page=2&size=10&sort=0-1-3-0&filter=--fred
This is my own best solution so far, but it's not really elegant:
if (preg_match_all("/[^f]col\[\d+]=\d+/", $_SERVER['QUERY_STRING'], $matches)) {
foreach($matches[0] AS $sortinfo) {
if (preg_match_all("/\d+/", $sortinfo, $matches)) {
if(count($matches[0]) == 2) {
echo "Col: ".$matches[0][0]."<br/>";
echo "Order: ".$matches[0][1]."<br/>";
}
}
}
}
It gives me the info I need
Col: 0
Order: 1
Col: 1
Order: 0
But is clumbsy. Is there a better way?

Rails send four backslashes using Net::HTTP

My rails application need to send some data to a php application, which expects a POST call.
I use the folowing code:
uri = URI.parse(apiUrl)
req = Net::HTTP::Post.new(uri.to_s, initheader = {'Content-Type' =>'application/json'})
req.basic_auth(api_key, token)
req.set_form_data({"action" => action, "data" => data})
http = Net::HTTP.new(uri.host, uri.port)
response = http.request(req)
Where data is a hash converted to json:
data = {
:key1 => val1,
:key2 => val2
}.to_json
(it is a nested hash, i.e. some values are hash as well)
My problem is that the php application receives 4 backslashes before each quotation mark:
$data_json = $_POST['data'];
error_log($data_json);
and in error log I see:
'{\\\\"key1\\\\":val1,\\\\"key2\\\\":\\\\"val2\\\\"}'
Looks like rails add one of them, but even if I remove it and replace it with the following code:
a.gsub!(/\"/, '\'')
I still get many backslashes inside the php application, hence cannot convert the string to array.
Any idea??
By using set_form_data net/http is POSTing the form as urlencoded. Its NOT posting your request body as pure JSON.
If you want to POST raw JSON you will need to follow a pattern like:
uri = URI('https://myapp.com/api/v1/resource')
req = Net::HTTP::Post.new(uri, initheader = {'Content-Type' =>'application/json'})
req.body = {param1: 'some value', param2: 'some other value'}.to_json
res = Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request(req)
end

Posting JSON to PHP script

I am stuck a long time with trying to send a JSON from javascript to a PHP script : the sending is fine (I can see the JSON in fiddler) yet I receive nothing in the PHP script :
javascript:
var person = {
name: 'yoel',
age: 28
};
xmlhttp.open("POST","http://localhost:8888/statisticsdb.php",true);
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.send(JSON.stringify(person));
php :
echo 'trying to print ' . var_dump($_POST["name"]);
I would expect obviously to see SOMETHING but var_dump returns nothing. Help would be much appreciated!
try:
$data = json_decode(file_get_contents('php://input'));
var_dump($data->name);
the reason for this is, that the body of your POST-request is:
{"name":"yoel","age":28}
though, php expects something like (ref):
name=yoel&age=28
The json string can not be parsed properly, and thus $_POST will be empty.
$_POST holds value decoded from request having Content-Type application/x-www-form-urlencoded, i.e. it parses:
param1=value1&param2=value2
into:
array( 'param1' => 'value1', 'param2' => 'value2')
If you send data in json format, you have to json_decode it from the raw php input:
$input = file_get_contents('php://input');
$jsonData = json_decode($input);
And you'll have a PHP object filled with your json stuff.
Add this:
xmlhttp.setRequestHeader("Content-length", JSON.stringify(person).length);

jquery Autocomplete working with older versions of the browsers but not new ones?

here is the JSON data for my auto complete
{ "list" : [ {
"genericIndicatorId" : 100,
"isActive" : false,
"maxValue" : null,
"minValue" : null,
"modificationDate" : 1283904000000,
"monotone" : 1,
"name":"Abbau",
"old_name" : "abbau_change_delete_imac",
"position" : 2,
"systemGraphics" : "000000",
"unitId" : 1,
"valueType" : 1,
"description" : "Abbau",
"weight" : 1
}]}
and the code which i wrote is
$("#<portlet:namespace />giName").autocomplete({
source :`enter code here` function( request, response ) {
$.post(
"<%=AJAXgetGIs%>",
{
"<%=Constants.INDICATOR_NAME%>" : request.term,
"<%=Constants.SERVICE_ID%>" : <%=serviceId%>
},
function( data ) {
response( $.map( data.list, function( item ) {
//alert(item.name + " || " + item.genericIndicatorId);
item.value = item.name;
return item;
}));
},
"json"
);
},
minLength : 2
i am using jquery-ui-1.8.14.autocomplete.min.js plugin for auto complete
the problem i am getting is it is not showing all the matched results in new browsers.
for example if i type "an" in which should matches to the "anzahl" keyword, the fire bug is showing error like "bad control character literal in a string". results are showing for the letters "as,sa....". any help would be appriciated
thank you
The error message means you have control characters in your JSON response (something like \n, \t, etc). Newlines and the other control characters are not allowed in JSON strings, according to ECMA262 5ed. You can fix it rather easily by escaping or removing those characters, either from PHP or from Javascript.
Here you can find an example of how you can fix it from PHP, as the problem most likely comes from json_encode (which I assume you're using): http://codepad.org/Qu7uPt0E
As you can see, json_encode doesn't escape the \n so you have to do it manually before outputting.
Now for the mistery related to older browsers. If you look at jQuery's parseJSON function you'll notice that it first tries to parse the string with the browser's builtin JSON object and if it doesn't find any, it will just do a (sort of) eval (which will work even with newlines). So it probably works for you on Firefox < 3.5 or IE < 8 which don't have a native JSON object.
Also, it probably works with other search terms (like as, etc) simply because they don't include a result which has control characters.
Adding to draevors correct answer.
Look at downloading the JSON2 library
https://github.com/douglascrockford/JSON-js
That is how i got around this problem

Categories