I know this has been asked a few times but please bear with me.
I have a google maps object which is rather complex (it contains various nodes, coordinates, etc) and I am trying to pass it as a query string.
I need a play javascript/jQuery solution.
I have tried the .param method which gives a jQuery error. The only thing that works is the "stringify" method which then creates a string that when appearing as a url looks a bit like this: %7B%5C"shape_1%5C"%3A%7B%5C"color%5C"%3A%5C"%237F0000%5C"%2C%5C"data%5C"%3A%7B%5C"b%5C"%3A%5B%7B%5C"Na%5C"%3A51.56727431757122%2C%5C"Oa%5C"%3A-0.10462402858888709%7D%2C....
php translates that as:
{\\"shape_1\\":{\\"color\\":\\"#7F0000\\",\\"data\\":{\\"b\\":[{\\"Na\\":51.56727431757122,\\"Oa\\":-0.10462402858888709},...
but having said that I don't want to use PHP, I am just showing you what it does in case it helps you see what stringify did to the object.
After I unescape with Javascript it looks a bit more normal like:
{\"shape_1\":{\"color\":\"#7F0000\",\"data\":{\"b\":[{\"Na\":51.56727431757122,\"Oa\":-0.10462402858888709},..
So as you can see, the unescaped sequence has these slashes everywhere.
When I try to evaluate that into a JSON object I get "Illegal token \". The parse method also fails. I just can't find any way to put this string back into the complex JSON object that it was.
I have looked online for various suggestions but they fail. I also don't understand why stringify injects all these slashes which simply shouldn't be there.
If anyone has an idea how to take that object, put it in a query string and then parse it back I would be very grateful.
Nick
Update:
The answer is this:
encodeURIComponent(JSON.stringify(myObject));
And then on the receiving end:
var a = querySt("data");
var b = decodeURIComponent(a);
var c = unescape(b);
var d = JSON.parse(c);
or all in one line
JSON.parse(unescape(decodeURIComponent(querySt("data"))));
Nick
See http://php.net/manual/de/security.magicquotes.php - you have to turn off magic quotes. They are old, deprecated stuff, they are insecure and break stuff.
Magic Quotes is a process that automagically escapes incoming data to the PHP script. It's preferred to code with magic quotes off and to instead escape the data at runtime, as needed.
Howto: http://www.php.net/manual/de/security.magicquotes.disabling.php
Try this to convert query string into json object
var queryStringToJSON = function (url) {
if (url === '')
return '';
var pairs = (url || location.search).slice(1).split('&');
var result = {};
for (var idx in pairs) {
var pair = pairs[idx].split('=');
if (!!pair[0])
result[pair[0].toLowerCase()] = decodeURIComponent(pair[1] || '');
}
return result;
}
You can use jQuery.param method to covert json object back to query string
Related
I'm developing an iOS app with Xcode and Swift.
I need to load some data from my MySQL database in my app. I think it's reasonable to do this with JSON (or is there something against it?).
To make it easier I want to use SwiftyJSON-master.
I found this working code on SO:
class ViewController: UIViewController {
var dict = NSDictionary()
#IBOutlet weak var authorLbl: UILabel!
#IBOutlet weak var quoteLbl: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let urlString = "http://api.theysaidso.com/qod.json"
if let url = NSURL(string: urlString) {
if let data = try? NSData(contentsOfURL: url, options: []) {
let json = JSON(data: data)
print(json)
let auther = json["contents"]["quotes"][0]["author"].stringValue
let quote = json["contents"]["quotes"][0]["quote"].stringValue
authorLbl.text = auther
quoteLbl.text = quote
}
}
}
}
But when trying it with my own PHP script it doesn't work.
I think it's because of the different outputs. The (working) PHP script from the SO post I found is like this:
{"success":{"total":1},"contents":{"quotes":[{"quote":"I put instant coffee in a microwave oven and almost went back in time.","length":"70","author":"Steven Wright","tags":["coffee","funny","humor","thetimes","time"],"category":"funny","id":"LvFg2QsKr_FoCH_lwryQ5geF"}]}}
Using my own PHP scrip output is like this:
[{"a":"John Eve","b":"Cupertino","c":"Green","d":"Apple"},{"a":"Sarah Jones","b":"Berlin","c":"Red","d":"Pear"}]
The syntax seem to bee completely different.
This is my PHP script/code:
<?php
$root = realpath($_SERVER["DOCUMENT_ROOT"]);
include "$root/config.php";
$query = "SELECT * FROM users";
$stmt = $pdo->prepare($query);
$stmt->execute();
$userData = array();
while($row=$stmt->fetch(PDO::FETCH_ASSOC)){
$userData[] = $row;
}
echo json_encode($userData);
?>
What am I doing wrong? How can I influence the syntax? Or is it another problem?
P.S.: Is it reasonable to use this library or is something against it?
Update
Your php file returns a correct json format. You can access to the data simply like this:
print(json[0]["a"]) // John Eve
print(json[0]["b"]) // Cupertino
// ...
print(json[1]["a"]) // Sarah Jones
print(json[1]["c"]) // Red
Analyzing The JSON Syntax
In pursuit of understanding why is there a difference between the previous two JSON syntaxes, you need to learn about JSON Syntax.
I will try to explain that to you very briefly.
I know that I'm bad at writing in English, but I'll do my best.
Curly Braces
The curly braces in json syntax represent a json object like:
{"a":"John Eve","b":"Cupertino","c":"Green","d":"Apple"}
{"a":"Sarah Jones","b":"Berlin","c":"Red","d":"Pear"}
Square Brackets
The square brackets in json syntax represent an array of json objects like:
[
{"a":"John Eve","b":"Cupertino","c":"Green","d":"Apple"},
{"a":"Sarah Jones","b":"Berlin","c":"Red","d":"Pear"}
]
So, in the theysaidso's case, the JSON syntax represents a single JSON object that is:
The JSON object above has two JSON objects inside of it, the first object is:
"success":{"total":1}
the second one represents the contents:
Inside of the content of the JSON object, there is a JSON object called quotes which hold an array of json objects :)
Therefore, when you want to access an object of that nested json object you do this:
json["contents"]["quotes"][0]["author"].stringValue
In the above code you say:
return a property of string type called "author" -["author"]- that is in a json object at index of 0 -["quotes"][0]- in the quotes array in the contents object -["contents"]- in my json object -json-!
As for your case, you have a single json object that is an array of JSON objects:
Therefore, when you want to access an object of that nested JSON object you do this:
json[0]["a"]
In the above code you say:
return a property called "a" -["a"]- that is in a json object at index of 0 -json[0]- in the json object array -json-!
I hope you can understand what I'm trying to say.
All,
I'm trying to pass a stringified json object as a GET parameter but the receiving URL seems unable to decode it, I am not sure why.
Here is the relevant code:
Client side Json object production (works fine):
function createJson(){
// This works fine. It creates a json objects with three elements, the third being an array.
//(omitted code for brevity)
return jsonData;
}
Client side ajax call (works fine):
function recordSetGet(jsonData){
request = createRequest();
var rawSet=JSON.stringify(jsonData);
var encodedSet=encodeURIComponent(rawSet);
var params="set="+encodedSet;
var url= "Ajax_recordSetGet.php?"+params;
request.open("GET", url, true);
request.onreadystatechange = function(){}
request.send(null);
}
This yield the following URL: Ajax_recordSetGet.php?set=%7B%22setTitle%22%3A%22test%22%2C%22setTags%22%3A%22test%20%22%2C%22set%22%3A%5B%7B%22first%22%3A%22Joe%22%2C%22last%22%3A%22Doe%22%2C%22checked%22%3Atrue%7D%5D%7D"
Server side treatment:
<?php
header('Content-Type:text/html; charset=UTF-8');
if(!session_id()){
session_start();
}
if(isset($_GET['set'])){
$set=$_GET['set'];//This is the URI encoded string
var_dump ($set);
var_dump (json_decode($set));
var_dump ("Json last error is ".json_last_error());
}
?>
The result of the var_dumps are:
string '{"setTitle":"test","setTags":"test ","set":[{"first":"Joe","last":"Doe","checked":true}]}"' (length=90)
null
string 'Json last error is 4' (length=20)
So why is json_decode() failing here? The json_last_error() result suggests a syntax error.
Edit: Note that json_decode also fails if I send a non encoded string:
If I build the param string without encoding it like this:
var rawSet=JSON.stringify(jsonData);
var params="set="+rawSet;
var url= "Ajax_recordSetGet.php?"+params;
Then the URL becomes Ajax_recordSetGet.php?set={"setTitle":"test","setTags":"test ","set":[{"first":"Joe","last":"Doe","checked":true}]}"
And the receiving URL var_dump yield the same error:
string '{"setTitle":"test","setTags":"test ","set":[{"first":"Joe","last":"Doe","checked":true}]}"' (length=90)
null
string 'Json last error is 4' (length=20)
I don't know why, but you have a trailing double quote in your URL that messes up the JSON decode process.
...%7D%5D%7D" <- Trailing double quote
This quote also shows up in your dump of the set variable:
...true}]}"' (length=90) <- double quote is inside the string, the single quote is part of the var_dump output.
This double quote must be introduced in the Javascript code, although I cannot see a spot where that should happen. But your debugging should take place in that part of the system.
Note that you MUST NOT urldecode the string passed as the "set" parameter, as PHP has done the decoding for you already. But with the trailing double quote you cannot call json_decode().
As a quick proof of concept, try using $set = rtrim($set, '"') in your PHP code before decoding to remove that quote character.
http://php.net/manual/en/function.urldecode.php
The superglobals $_GET and $_REQUEST are already decoded. Using urldecode() on an element in $_GET or $_REQUEST could have unexpected and dangerous results.
Try a different way. I suggest base64-encoding the json string.
Instead of this:
var rawSet=JSON.stringify(jsonData);
var encodedSet=encodeURIComponent(rawSet);
var params="set="+encodedSet;
var url= "Ajax_recordSetGet.php?"+params;
do this:
var rawSet=JSON.stringify(jsonData);
var encodedSet=btoa(rawSet);
var params="set="+encodedSet;
var url= "Ajax_recordSetGet.php?"+params;
But pay attention to the caveats!
And in your serverside:
$decodedSet=json_decode(base64_decode($set));
I have a JS function which I'm passing some JSON. I produce this JSON with PHP:
<?php
$array[] = array('hello','123','456');
echo json_encode($array);
?>
This gives me something neat for JS like:
[["hello","123","456"]]
My JS function seems to like this format.
The problem I have however is when I produce a similar array directly in JS like so:
var json = [[text_var,number_var,number_var]]; // these vars established earlier in the code
var json_stringify = JSON.stringify(json);
I wind up with something that looks like this:
[["hello",123,456]]
So basically, it isn't encapsulating my numbers with quotes. I wouldn't think it would matter, but without them I get a Uncaught RangeError: Maximum call stack size exceeded
I tried doing something like preparing the JSON myself with:
var json = '[["'+place_name+'","'+longitude+'","'+latitude+'"]]';
But passing that it doesn't like either - maybe it isn't feeling it as a JSON var, and I've tried parsing that through JSON.stringify but I end up with backslashes before every quote and it doesn't like that either.
What is my feeble mind not seeing here?
EDIT: My PHP array is in another array hence the result of [["hello',"123","456"]] and not single brackets [ ]
Convert numbers to strings:
var json = [[text_var,number_var.toString(),number_var.toString()]];
JSON supports numbers (without quotes) and strings (with quotes). To force it to use strings, try:
var json = [[text_var,number_var + "",number_var + ""]];
Am trying to pass an array of values from PHP function to Javascript. Not sure if I am doing it correctly.
PHP:
function toggleLayers(){
for($i=0;$i<$group_layer_row;$i++){
$toggleArray=mb_convert_encoding(mssql_result ($rs_group_layer, $i, 0),"UTF-8","SJIS")."_".mb_convert_encoding(mssql_result ($rs_group_layer, $i, 1),"UTF-8","SJIS");
return $toggleArray;
}
}
JS:
var myArray = [JSON.parse("<?php echo json_encode($toggleArray); ?>")];
for(var i=0;i < myArray.length; i++){
if($myArray.getVisibility()==true){
$myArray.getVisibility(false);
}
else{
$myArray.getVisibility(true);
}
}
SQL (for reference):
$con = mssql_connect("myServer", "myUsername", myPassword");
$sql = "SELECT * FROM m_group_layer WHERE group_id=\"".$_SESSION["group_id"]."\" ORDER BY display_order";
$rs_group_layer = mssql_query ($sql, $con);
$group_layer_row = mssql_num_rows($rs_group_layer);
I have been looking at some other similar questions, and the answers are either vague and/or there are a few thousand of them.
Would appreciate any help, also please try to explain as if you were writing a book called "Idiot's Guide to Passing PHP Arrays to JS"
Thanks for your help.
Edit:
Sorry, my question was very vague. Here's what I'm trying to do:
1.PHP Function gets all records from table into array(in this case they are map layers)
2.Javascript receives PHP array and loops through adding if clause to toggle layers.
Hope this makes it clearer.
It's simpler than you think.
Change this line:
var myArray = [JSON.parse("<?php echo json_encode($toggleArray); ?>")];
To just:
var myArray = <?php echo htmlspecialchars(json_encode($toggleArray), ENT_NOQUOTES); ?>;
json_encode produces a json string. Echoing the string into a javascript context is the equivalent of a javascript literal. The htmlspecialchars is just for the necessary html escaping and is not unique to echoing json.
NOTE however that you can only json_encode a php object or array, not any scalar types like ints or strings. This is a limitation of JSON itself. In your toggleLayers() function, you are returning a string, not an array.
A thing that would be very useful to understand:
You sumply can't "pass an array of values from PHP function to Javascript".
But rather you have to create the javascript code using PHP just like you are creating HTML.
Thus, 3 simple step to solve any problem with PHP -> client transfers:
Create a pure client-side code you wish. Make it work. Save it somewhere.
Create a PHP code to produce that client-side code.
Compare the codes. If doesn't match - correct the PHP code. Repeat until done.
Some have see that code :
<?php
echo stripslashes(json_encode(glob("photos-".$_GET["folder"].'/*.jpg')));
?>
it echo a really nice perfect string like that :
["photos-animaux/ani-01.jpg","photos-animaux/ani-02.jpg","photos-animaux/ani-02b.jpg","photos-animaux/ani-03.jpg","photos-animaux/ani-04.jpg","photos-animaux/ani-05.jpg","photos-animaux/ani-06.jpg","photos-animaux/ani-07.jpg","photos-animaux/ani-08.jpg","photos-animaux/ani-09.jpg","photos-animaux/ani-10.jpg","photos-animaux/ani-11.jpg","photos-animaux/ani-12.jpg","photos-animaux/ani-13.jpg","photos-animaux/ani-14.jpg"]
With json encode it shoul send a array so variable[0] should = to photos-animaux/ani-01.jpg
NOW it is only the fisrt caracter of the string..
how a array get converted to string, and how in javascipt to convert string to array to be able to get value [0] [1] etc..
the question is WHEN or WHY the perfect array get converted to string anyway ?
Using JSON.parse(), from the library available here, is preferable to using eval() since this only reads JSON strings and hence avoids the inherant security risks associated with eval().
In order to parse a JSON-encoded string into actual javascript objects, you need to eval() the data returned in order for javascript to execute against the data:
var data = eval(json_string)
Keep in mind that you should only ever run eval on a string when you trust the source and are sure that there is no possibility of a script injection attack, since javascript will run everything present in the string.
Use one of the JSON libraries listed at the bottom of http://json.org/
WHEN or WHY
If I understood correctly, the answer to both is json_encode(): check out the documentation. Converting a variable to a string (often called serialization or flattening) is a quite common operation.