I've used json_encode($array); to convert an array to a json.
[{"x":1418736600,"y":"82.2"},{"x":1418736900,"y":"82.2"}]
But what I really need is a JavaScript object like the following:
[{x:1418736600,y:"82.2"},{x:1418736900,y:"82.2"}]
To make it short I would like a JSON without quoting the keys, but it would be preferable avoiding parsing what json_encode outputs and using a more straightforward way instead.
Is it possible to do this in PHP?
Other than making the payload very slightly smaller, there's no need to do this. The output of json_encode is valid JavaScript code, if used where a value is expected, e.g.:
var x = <?php echo json_encode($array); ?>;
The quoted property keys are valid JavaScript. JSON as a whole is, in fact, a subset of JavaScript literal syntax.
You could throw a regular expression at the result. It can probably never be perfect (JSON, like HTML, can't be correctly parsed with a single regular expression), but within a limited domain you might be able to do it. For instance, here's a naive version that would probably work for many data sets, including your example, though again it would not work with all data sets by any means:
<?php
$str = json_encode($array);
$str = preg_replace('/"([A-Za-z0-9_$]+)":/', '$1:', $str);
?>
var x = <?php echo json_encode($array); ?>;
That assumes anything that consists of just A-Z, a-z, 0-9, _, or $ between double quotes followed immediately by a colon is a key and removes the quotes. (That's not a complete list of valid JavaScript identifier characters, it's just an example.)
But it seems unlikely to me that the savings are worth the bother.
To do it correctly, of course, you'd have to do your own serializer. It wouldn't be all that hard, just a recursive function that handles descending into arrays and objects. It could still use json_encode for the values.
Related
I want to pass an php array to js. For this purpose I use json_encode an then in js JSON.parse().
Now the Problem ist, that JSON.parse trow an exception 'missing ) after argument list'. I guess it's apostrophes in numbers (number_format > CHF).
clippings:
<script>
(function($) {
var prices = JSON.parse('<?= $this->prices_json; ?>'); ...
... "offsetdruck_4f":{"1s":"583.82","2s":"1'090.09"}...
have single quotes to be escaped? If so, how best to do it?
is json_encode an then in js JSON.parse the best practice to pass an php-Array to js (at a template)? If not, how best to do it?
have single quotes to be escaped?
Single quotes inside a JavaScript string literal that is delimited with single quotes do have to be escaped.
… and that is what you have: 'data with ' and then at the end'.
If so, how best to do it?
To not use a JavaScript string literal at all.
JSON is a subset of JavaScript literal notation, so just treat it as JavaScript. Don't try wrapping it in a string and then explicitly parsing it.
var prices = <?= $this->prices_json; ?>;
try php: addslashes(json_encode($php array))
have single quotes to be escaped? If so, how best to do it?
json_encode should escape everything needs to be escaped.
is json_encode an then in js JSON.parse the best practice to pass an php-Array to js (at a template)? If not, how best to do it?
You should use json_encode in order to be sure that the output is correct. Do not rely on default array output. It has nothing to do with JSON.
You don't need to use JSON.parse here at all.
var prices = <?= json_encode($this->prices_json); ?>;
I'm trying to use the php GET method to create an array of keywords from a keywordBox field on another page.
Here is an example of the keywords appended to the page URL:
/searchResults.php?keywordBox=computing+finance
This looks okay to me but when I convert to a JSON object it seems the keywords become a single string ("computing finance") rather than array of strings (["computing", "finance"])
var keywords = <?php echo json_encode($_GET['keywordBox']) ?>;
alert(keywords[0]); // output "c"
I thought this would output the first word in the array "computing" instead it outputs the first character "c" so I'm a little confused and new to these languages. Any explanation greatly appreciated.
keywordBox can be an array, just change your query string with:
?keywordBox[]=computing&keywordBox[]=finance
Otherwise you can keep it as a string, and explode it.
var keywords = <?php echo json_encode(explode(' ', $_GET['keywordBox'])) ?>;
Pay attention to what you're encoding.
This only encodes one GET parameter, not the $_GET superglobal array:
var keywords = <?php echo json_encode($_GET['keywordBox']) ?>;
With your given URL and the parameter keywordBox=computing+finance, $_GET['keywordBox'] will contain a single string, "computing finance", not an array. If you want the parameter to contain an array, you need to use array notation, as in keywordBox[]=computing&keywordBox[]=finance.
I encoded an array using json_encode() function and it gave me a string like this..
"[{"details":"power - 2000w \nac-220-240v \/ 50-60hz\n369 degree cordless base\n","model_id":"MC-EK3428 \/ MC-EK3328"}]"
as you can see it contains special characters like "\n"..I want these special characters to be replaced with "" because in javascript I am using the JSON.parse(); function to convert this string to an object..
but it gives me an error
syntaxerror : missing ) after argument list
I think this is because of the special characters in the string..how can I escape these?
Edit
php :
$view->jsonencoded_array = json_encode($array);
javascript :
var products = JSON.parse('<?php echo $jsonencoded_array; ?>');//this line gives me the error
update :
found out that the error is given in this :
'<?php echo $jsonencoded_array; ?>'
The problem here is that \n (and various other combinations) have special meaning inside a JavaScript string, and you are dumping your JSON into a JavaScript string without doing any conversion of those characters.
Since JSON is heavily inspired by JavaScript literal syntax, you can use json_encode to convert a PHP string into a JavaScript string.
There are some gotchas, the main one being that </script> can appear in a JSON text without causing any problems, but having that in the middle of your JavaScript <script> element is going to cause the HTML parser to cut off your JavaScript in the middle of the string … but PHP's default encoding rules will generate <\/script> which solves that problem.
So:
<?php
$json_array = json_encode($array);
$javascript_string = $json_encode($json_array);
?>
var products = JSON.parse(<?php echo $javascript_string; ?>);
That said. A JSON array is also a JavaScript array, so you can skip that step entirely.
<?php
$json_array = json_encode($array);
?>
var products = <?php echo $json_array; ?>;
There must something that you are missing or there is some other reason for your issue while parsing in JavaScript; because json_encode handles \n and other special characters such " \ etc. very well and escape them properly without any explicit work.
I would suggest you to check the JSON produced and you are supplying to JavaScript and see if there is something missing in between.
Note: You can do a str_replace but it is not advised. Better stick to json_encodesince its s standard function and it works well.
Edit:
You should be echoing $view->jsonencoded_array not just $jsonencoded_array, no need to parse already JSON object.
php :
$view->jsonencoded_array = json_encode($array);
javascript :
var products = <?php echo $view->jsonencoded_array; ?>;
json_encode() twice helped me to solve this issue..
$view->jsonencoded = json_encode(json_encode($array));
I'm having trouble escaping a quotation mark in PHP.
I have a table of products and each row has an onclick function, with the name of the product as the argument.
The name contains the length which is measured in inches, so the name contains a quotation mark. I wrapped an addslashes() around the string. This adds a backslash before the quotation mark but for some reason it doesn't seem to escape the character!
Here's a snippet of my code:
<?$desc1 = addslashes($row['Desc1']);?>
<tr class='tableRow' onclick='afterProductSelection("<?=$desc1?>")'>
<td><?=$row['Desc1']?></td>
When I inspect element in Google Chrome, the colour of the syntax indicates that this has not been escaped, clicking on it gives me a syntax error.
Probably something simple that I'm missing. Hope you can help!
There are a lot of different cases where you need to escape a string. addslashes() is the wrong answer to pretty much all of them.
The addslashes() function is an obsolete hang-over from PHP's early days; it is not suitable for any escaping. Don't use it. Ever. For anything.
In your particular case, since you're creating Javascript data from PHP, use json_encode().
json_encode() will take a PHP variable (whether it's a string, array, object or whatever) and convert it into a JSON string. A JSON string is basically fully escaped Javascript variable, including the quotes around your strings, etc. This is what you need to do.
The addslashes() function is an obsolete hang-over from PHP's early days; it is not suitable for any escaping. Don't use it. Ever. For anything. -Spudley
I think the function you're looking for is htmlentities()
<?=htmlentities($desc1, ENT_QUOTES)?>
http://ca1.php.net/htmlentities
You are generating a JavaScript string encoded as HTML so you need to encode twice:
Use json_encode() to generate the string
Use htmlspecialchars() to encode as HTML
Use json_encode to output variables from the backend in JavaScript:
<tr onclick='afterProductSelection(<? print json_encode($desc1); ?>)'>
N.B.: For string output there is no need for extra quotes.
I’m making requests to my server using jQuery.post() and my server is returning JSON objects (like { "var": "value", ... }). However, if any of the values contains a single quote (properly escaped like \'), jQuery fails to parse an otherwise valid JSON string. Here’s an example of what I mean (done in Chrome’s console):
data = "{ \"status\": \"success\", \"newHtml\": \"Hello \\\'x\" }";
eval("x = " + data); // { newHtml: "Hello 'x", status: "success" }
$.parseJSON(data); // Invalid JSON: { "status": "success", "newHtml": "Hello \'x" }
Is this normal? Is there no way to properly pass a single quote via JSON?
According to the state machine diagram on the JSON website, only escaped double-quote characters are allowed, not single-quotes. Single quote characters do not need to be escaped:
Update - More information for those that are interested:
Douglas Crockford does not specifically say why the JSON specification does not allow escaped single quotes within strings. However, during his discussion of JSON in Appendix E of JavaScript: The Good Parts, he writes:
JSON's design goals were to be minimal, portable, textual, and a subset of JavaScript. The less we need to agree on in order to interoperate, the more easily we can interoperate.
So perhaps he decided to only allow strings to be defined using double-quotes since this is one less rule that all JSON implementations must agree on. As a result, it is impossible for a single quote character within a string to accidentally terminate the string, because by definition a string can only be terminated by a double-quote character. Hence there is no need to allow escaping of a single quote character in the formal specification.
Digging a little bit deeper, Crockford's org.json implementation of JSON for Java is more permissible and does allow single quote characters:
The texts produced by the toString methods strictly conform to the JSON syntax rules. The constructors are more forgiving in the texts they will accept:
...
Strings may be quoted with ' (single quote).
This is confirmed by the JSONTokener source code. The nextString method accepts escaped single quote characters and treats them just like double-quote characters:
public String nextString(char quote) throws JSONException {
char c;
StringBuffer sb = new StringBuffer();
for (;;) {
c = next();
switch (c) {
...
case '\\':
c = this.next();
switch (c) {
...
case '"':
case '\'':
case '\\':
case '/':
sb.append(c);
break;
...
At the top of the method is an informative comment:
The formal JSON format does not allow strings in single quotes, but an implementation is allowed to accept them.
So some implementations will accept single quotes - but you should not rely on this. Many popular implementations are quite restrictive in this regard and will reject JSON that contains single quoted strings and/or escaped single quotes.
Finally to tie this back to the original question, jQuery.parseJSON first attempts to use the browser's native JSON parser or a loaded library such as json2.js where applicable (which on a side note is the library the jQuery logic is based on if JSON is not defined). Thus jQuery can only be as permissive as that underlying implementation:
parseJSON: function( data ) {
...
// Attempt to parse using the native JSON parser first
if ( window.JSON && window.JSON.parse ) {
return window.JSON.parse( data );
}
...
jQuery.error( "Invalid JSON: " + data );
},
As far as I know these implementations only adhere to the official JSON specification and do not accept single quotes, hence neither does jQuery.
If you need a single quote inside of a string, since \' is undefined by the spec, use \u0027 see http://www.utf8-chartable.de/ for all of them
edit: please excuse my misuse of the word backticks in the comments. I meant backslash. My point here is that in the event you have nested strings inside other strings, I think it can be more useful and readable to use unicode instead of lots of backslashes to escape a single quote. If you are not nested however it truly is easier to just put a plain old quote in there.
I understand where the problem lies and when I look at the specs its clear that unescaped single quotes should be parsed correctly.
I am using jquery`s jQuery.parseJSON function to parse the JSON string but still getting the parse error when there is a single quote in the data that is prepared with json_encode.
Could it be a mistake in my implementation that looks like this (PHP - server side):
$data = array();
$elem = array();
$elem['name'] = 'Erik';
$elem['position'] = 'PHP Programmer';
$data[] = json_encode($elem);
$elem = array();
$elem['name'] = 'Carl';
$elem['position'] = 'C Programmer';
$data[] = json_encode($elem);
$jsonString = "[" . implode(", ", $data) . "]";
The final step is that I store the JSON encoded string into an JS variable:
<script type="text/javascript">
employees = jQuery.parseJSON('<?=$marker; ?>');
</script>
If I use "" instead of '' it still throws an error.
SOLUTION:
The only thing that worked for me was to use bitmask JSON_HEX_APOS to convert the single quotes like this:
json_encode($tmp, JSON_HEX_APOS);
Is there another way of tackle this issue? Is my code wrong or poorly written?
Thanks
When You are sending a single quote in a query
empid = " T'via"
empid =escape(empid)
When You get the value including a single quote
var xxx = request.QueryString("empid")
xxx= unscape(xxx)
If you want to search/ insert the value which includes a single quote in a query
xxx=Replace(empid,"'","''")
Striking a similar issue using CakePHP to output a JavaScript script-block using PHP's native json_encode. $contractorCompanies contains values that have single quotation marks and as explained above and expected json_encode($contractorCompanies) doesn't escape them because its valid JSON.
<?php $this->Html->scriptBlock("var contractorCompanies = jQuery.parseJSON( '".(json_encode($contractorCompanies)."' );"); ?>
By adding addslashes() around the JSON encoded string you then escape the quotation marks allowing Cake / PHP to echo the correct javascript to the browser. JS errors disappear.
<?php $this->Html->scriptBlock("var contractorCompanies = jQuery.parseJSON( '".addslashes(json_encode($contractorCompanies))."' );"); ?>
I was trying to save a JSON object from a XHR request into a HTML5 data-* attribute. I tried many of above solutions with no success.
What I finally end up doing was replacing the single quote ' with it code ' using a regex after the stringify() method call the following way:
var productToString = JSON.stringify(productObject);
var quoteReplaced = productToString.replace(/'/g, "'");
var anchor = '<a data-product=\'' + quoteReplaced + '\' href=\'#\'>' + productObject.name + '</a>';
// Here you can use the "anchor" variable to update your DOM element.
Interesting. How are you generating your JSON on the server end? Are you using a library function (such as json_encode in PHP), or are you building the JSON string by hand?
The only thing that grabs my attention is the escape apostrophe (\'). Seeing as you're using double quotes, as you indeed should, there is no need to escape single quotes. I can't check if that is indeed the cause for your jQuery error, as I haven't updated to version 1.4.1 myself yet.