Will php's json_encode() always use double quotes as string delimiter? - php

I have a php associative array containing strings as values and I encode it to JSON and store it in an html-data attribute. That is read by some JS.
So far so good.
Now, I need to use single quotes for the data attribute, otherwise the context switches.
<section id="settings" data-settings='{"some":"val"}'>
</section>
The question is, can I rely on the json_encode() function of php to encode strings always with double quotes? Surprisingly, I can't seem to find information on this. I only find articles from people having issues with quotes in the array values.
Thanks in advance.

Yes, as defined in the JSON spec, the delimiter will always be ". However, values may contain ' characters, which would break your HTML. To keep it simple and not worry about what might or mightn't pose an issue, HTML-escape your values!
<section data-settings="<?= htmlspecialchars(json_encode($foo)); ?>"></section>
This is guaranteed to work, always, no matter what values you pipe in or how you encode them.
NOTE that htmlspecialchars will by default only encode ", not '; so you must use " as the delimiter in HTML (or change the default escaping behavior).

Double-quotes is just convention - standard in JSON in many languagues. So if you want to store JSON in HTML attribute with double-quotes. You can encode that
In PHP
$encoded_json = base64_encode(json_encode($var));
In HTML
<section id="settings" data-settings='<?=$encoded_json?>'>
In JS
var variable = JSON.parse(atob(encoded_json));

Related

How to remove escaping in PHP?

I have this URL parameter:
KKe%7bZoE_%24g)tjm%40
When I put it into a variable and echo it, the result is:
KKe{ZoE_$g)tjm#
How to avoid that?
Data in $_GET is already URL-decoded. If you require the original string, get it from $_SERVER['QUERY_STRING']. Note that you will have to process the query string yourself though, including breaking down the individual components.
Alternatively, use rawurlencode($_GET[..]) to re-encode the value; which may or may not produce slightly differently encoded values than you originally got.
Test it with html_entity_decode - it helpt me a lot with my inputs.
If the string is not shown as it is, you have urlencode() or htmlentities() somewhere in your code. Check that, you shouldn't encode html entities before echoing if you want the string to be intact.

Using variables containing special characters

I am working on a project and a lot of my variables need to contain special characters such as {}[].'"!?/\=+- and many more what is the safest way to pass these variables back and forth between SQL, PHP, and output? and how can I prevent a variable from interfering with my code? Ie:
<?php
echo $var;
echo '$var';
echo "$var";
?>
The best way would be to URL encode your data as soon as it is supplied. Then store it and when you are using it, urldecode it.
Something like
string urlencode ( string $str )
To encode and
string urldecode ( string $str )
To decode. This changes your "special" characters into safe characters.
In PHP, the name of a variable cannot contain special characters (other than the initial dollar sign $ and underscores _). The value of a variable can contain whatever you'd like so long as you follow the rules of defining PHP strings.
The variable values won't interfere with your code. If you're concerned about it interfering with your output HTML, use htmlspecialchars as Rocket Hazmat suggested in the comments.
You can use PDO/MYSQL for isnerting the data into the database..
For converting into html entites you can use htmlchars() function.
An example:
<?php
${'[\*var'} = 1;
echo ${'[\*var'};
https://3v4l.org/5Dr93

Escaping/encoding single quotes in JSON encoded HTML5 data attributes

In PHP, I use json_encode() to echo arrays in HTML5 data attributes.
As JSON requires - and json_encode() generates - values encapsulated by double quotes. I therefor wrap my data attributes with single quotes, like:
<article data-tags='["html5","jquery","php","test's"]'>
As you can see, the last tag (test's) contains a single quote, and using json_encode() with no options leads to parsing problems.
So I use json_encode() with the JSON_HEX_APOS parameter, and parsing is fine, as my single quotes are encoded, but I wonder: is there a downside doing it like this?
You need to HTML escape data echoed into HTML:
printf('<article data-tags="%s">',
htmlspecialchars(json_encode(array('html5', ...)), ENT_QUOTES, 'UTF-8'));
or use the build-in option:
json_encode(array('html5', ...), JSON_HEX_APOS)
you can check it up in the manual: http://php.net/manual/en/json.constants.php#constant.json-hex-apos

Passing special characters from php to javascript

I am passing a string variable from php to javascript.
The string contains "
But javascript doesn't get it.
How can I escape this character?
UPD:
To be more clear, first I don't want to make many changes in the code (not written by me)...
The string is passed this way:
var string = '<? echo $string;?>' ;
Single quotes are used. Maybe there is a way to change smth. in the string itself?
You could use the json_encode method:
<script type="text/javascript">
var value = <?php echo json_encode($someValue); ?>;
alert(value);
</script>
Assuming a string delimited using double quotes, add_slashes will do the job in the particular case.
Wrapping the data in an associative array, running it through json_encode and altering the JS to expect the changed data structure is a safer approach though (since that will take care of other characters which are significant, such as literal new lines).
(Technically speaking, with the current implementation of json_encode you could skip wrapping it in an associative array … but a plain string isn't valid JSON and I'm inclined to avoid depending on a function that is supposed to generate JSON not throwing an exception when given a data structure that can't be turned into JSON).
If you are embedding the script in an HTML document you will also have to take steps to ensure that the resulting JS doesn't contain any HTML that could cause issues (such as " in an script included as an attribute value).
Use urlencode() function in php code to pass the string to javascript code and decodeuri() in javascript to decode that string.

Using innerhtml to write html with A LOT of quotes

I'm trying to call a function which writes a very long string of html to an element. The string will look similar to this;
'<div id='gaugearray8'>
<p id='ANCPUB' class='plot' style='height:100px;width:175px;float:left;' title='0.0011217599587192' onClick=LowerLevelPrint([{"NumberSelected":1,"TargetPerc":[237.5],"KpiDescription":["Contribution&nbspof&nbspExternal&nbspRevenue"],"KpiName":["revcontrubionkpi"],"ValuetoPrint":[0.0011217599587192],"ValueNow":[19],"ValueCompare":[1693767],"Target":["8"],"KpiUnits":["Pounds"],"PercentCompare":[0.0011217599587192]}]) onmouseover=TopLevelLabel({"NumberSelected":1,"Description":["Contribution&nbspof&nbspExternal&nbspRevenue"],"GroupDescription":"Ancillary&nbspService&nbspPerformance"}) onmouseout=clearnew()></p>
<p id='CSPUB' class='plot' style='height:100px;width:175px;float:left;' title='21.855170547342' onClick=LowerLevelPrint([{"NumberSelected":7,"TargetPerc":[206.03360584712,8.8767313176762,10.356186537289,12.5,12.5,237.5,10.356186537289],"KpiDescription":["Operating&nbspCost&nbspper&nbspService&nbspKm","Revenue&nbspper&nbspService&nbspKm","Total&nbspCost&nbspper&nbspService&nbspKm","Claims&nbspCost&nbspper&nbspVehicle","Claims&nbspCost&nbspper&nbspDriver","Number&nbspof&nbspClaims&nbspLodged&nbspper&nbsp100,000km","Overheads&nbspCost&nbspper&nbspService&nbspKm"],"KpiName":["opcostperkmkpi","revenueperkmkpi","totalcostperkmkpi","claimspervehkpi","claimsperdriverkpi","claimslodgedkpi","overheadskpi"],"ValuetoPrint":[110.47252736225,5.6435200058102,5.434671444334,0.35610369406272,0.35829645079956,12.666666666667,18.054408207469],"ValueNow":[10.301680292356,0.62137119223733,0.62137119223733,1,1,19,0.62137119223733],"ValueCompare":[9.32510601353,11.010348002623,11.433463800009,280.81708128079,279.09849449204,150,3.4416591510336],"Target":["5","7","6","8","8","8","6"],"KpiUnits":["Pounds&nbspper&nbspKm","Pounds&nbspper&nbspKm","Pounds&nbspper&nbspKm","Pounds&nbspper&nbspVehicle","Pounds&nbspper&nbspDriver","Claims","Pounds&nbspa&nbspkm"],"PercentCompare":[110.47252736225,5.6435200058102,5.434671444334,0.35610369406272,0.35829645079956,12.666666666667,18.054408207469]}]) onmouseover=TopLevelLabel({"NumberSelected":7,"Description":["Operating&nbspCost&nbspper&nbspService&nbspKm","Revenue&nbspper&nbspService&nbspKm","Total&nbspCost&nbspper&nbspService&nbspKm","Claims&nbspCost&nbspper&nbspVehicle","Claims&nbspCost&nbspper&nbspDriver","Number&nbspof&nbspClaims&nbspLodged&nbspper&nbsp100,000km","Overheads&nbspCost&nbspper&nbspService&nbspKm"],"GroupDescription":"Core&nbspService&nbspPerformance"}) onmouseout=clearnew()></p>
<p id='ROPTUB' class='plot' style='height:100px;width:175px;float:left;' title='9.7292765723395' onClick=LowerLevelPrint([{"NumberSelected":2,"TargetPerc":[12.5,207.23684210526],"KpiDescription":["Revenue&nbspExpenditure&nbspper&nbspPassenger&nbspJourney","Cost&nbspPer&nbspHeadcount"],"KpiName":["revexperjourneykpi","coststaffkpi"],"ValuetoPrint":[19.044041148259,0.41451199641943],"ValueNow":[1,16.578947368421],"ValueCompare":[5.2509863437855,3999.6302909519],"Target":["8","8"],"KpiUnits":["Pounds&nbspper&nbspJourney","Pounds&nbspper&nbspStaff"],"PercentCompare":[19.044041148259,0.41451199641943]}]) onmouseover=TopLevelLabel({"NumberSelected":2,"Description":["Revenue&nbspExpenditure&nbspper&nbspPassenger&nbspJourney","Cost&nbspPer&nbspHeadcount"],"GroupDescription":"Resource&nbspOptimisation"}) onmouseout=clearnew()></p></div>';
Don't worry about disecting that as it's just an example of what can be sent. I'm assuming the problem is the multitude of quotes inside this string, as the javascript on the page entirely stops working when I include this function.
The above string is actually generated in a php loops, and the function I'm trying to use calls attempts
document.getElementById('financearea').innerHTML =
'<?php $myview->PopulateContent($finance, 8, 'ub', 'UB', $a); ?>';
`
Which works correctly when its in the main page body, but won't run when using the innerHTML method.
Does anyone have any suggestions on how this could work?
This is the code on the php side - its created and echo'd in a loop
$thisgoesinfile =
"<p id='".$Group.$Depot."' class='plot' style='height:100px;width:175px;float:left;' title='".$TotalValuetoPrint."' onClick=LowerLevelPrint(".json_encode($result_set).") onmouseover=TopLevelLabel(".json_encode($Descriptions).") onmouseout=clearnew()></p>";
Edit: I tried removing all the single quotes in the php string so now the string looks like
document.getElementById('financearea').innerHTML = <div id=gaugearray8><p id=ANCPUB class=plot style=height:100px;width:175px;float:left; title=0.0011217599587192 onClick=LowerLevelPrint([{"NumberSelected":1,"TargetPerc":[237.5],"KpiDescription":["Contribution&nbspof&nbspExternal&nbspRevenue"],"KpiName":["revcontrubionkpi"],"ValuetoPrint":[0.0011217599587192],"ValueNow":[19],"ValueCompare":[1693767],"Target":["8"],"KpiUnits":["Pounds"],"PercentCompare":[0.0011217599587192]}]) onmouseover=TopLevelLabel({"NumberSelected":1,"Description":["Contribution&nbspof&nbspExternal&nbspRevenue"],"GroupDescription":"Ancillary&nbspService&nbspPerformance"}) onmouseout=clearnew()></p><p id=CSPUB class=plot style=height:100px;width:175px;float:left; title=21.855170547342 onClick=LowerLevelPrint([{"NumberSelected":7,"TargetPerc":[206.03360584712,8.8767313176762,10.356186537289,12.5,12.5,237.5,10.356186537289],"KpiDescription":["Operating&nbspCost&nbspper&nbspService&nbspKm","Revenue&nbspper&nbspService&nbspKm","Total&nbspCost&nbspper&nbspService&nbspKm","Claims&nbspCost&nbspper&nbspVehicle","Claims&nbspCost&nbspper&nbspDriver","Number&nbspof&nbspClaims&nbspLodged&nbspper&nbsp100,000km","Overheads&nbspCost&nbspper&nbspService&nbspKm"],"KpiName":["opcostperkmkpi","revenueperkmkpi","totalcostperkmkpi","claimspervehkpi","claimsperdriverkpi","claimslodgedkpi","overheadskpi"],"ValuetoPrint":[110.47252736225,5.6435200058102,5.434671444334,0.35610369406272,0.35829645079956,12.666666666667,18.054408207469],"ValueNow":[10.301680292356,0.62137119223733,0.62137119223733,1,1,19,0.62137119223733],"ValueCompare":[9.32510601353,11.010348002623,11.433463800009,280.81708128079,279.09849449204,150,3.4416591510336],"Target":["5","7","6","8","8","8","6"],"KpiUnits":["Pounds&nbspper&nbspKm","Pounds&nbspper&nbspKm","Pounds&nbspper&nbspKm","Pounds&nbspper&nbspVehicle","Pounds&nbspper&nbspDriver","Claims","Pounds&nbspa&nbspkm"],"PercentCompare":[110.47252736225,5.6435200058102,5.434671444334,0.35610369406272,0.35829645079956,12.666666666667,18.054408207469]}]) onmouseover=TopLevelLabel({"NumberSelected":7,"Description":["Operating&nbspCost&nbspper&nbspService&nbspKm","Revenue&nbspper&nbspService&nbspKm","Total&nbspCost&nbspper&nbspService&nbspKm","Claims&nbspCost&nbspper&nbspVehicle","Claims&nbspCost&nbspper&nbspDriver","Number&nbspof&nbspClaims&nbspLodged&nbspper&nbsp100,000km","Overheads&nbspCost&nbspper&nbspService&nbspKm"],"GroupDescription":"Core&nbspService&nbspPerformance"}) onmouseout=clearnew()></p><p id=ROPTUB class=plot style=height:100px;width:175px;float:left; title=9.7292765723395 onClick=LowerLevelPrint([{"NumberSelected":2,"TargetPerc":[12.5,207.23684210526],"KpiDescription":["Revenue&nbspExpenditure&nbspper&nbspPassenger&nbspJourney","Cost&nbspPer&nbspHeadcount"],"KpiName":["revexperjourneykpi","coststaffkpi"],"ValuetoPrint":[19.044041148259,0.41451199641943],"ValueNow":[1,16.578947368421],"ValueCompare":[5.2509863437855,3999.6302909519],"Target":["8","8"],"KpiUnits":["Pounds&nbspper&nbspJourney","Pounds&nbspper&nbspStaff"],"PercentCompare":[19.044041148259,0.41451199641943]}]) onmouseover=TopLevelLabel({"NumberSelected":2,"Description":["Revenue&nbspExpenditure&nbspper&nbspPassenger&nbspJourney","Cost&nbspPer&nbspHeadcount"],"GroupDescription":"Resource&nbspOptimisation"}) onmouseout=clearnew()></p></div>;
But still not working.
Use json_encode rather than wrapping the text in single quotes yourself:
document.getElementById('financearea').innerHTML = <?php echo json_encode($myview->PopulateContent($finance, 8, 'ub', 'UB', $a)); ?>;
When you pass a string into json_encode, it will get wrapped in quotes and any quotes and other special characters within it will get correctly encoded for use as a JavaScript literal string. (This is a by-product of the fact that JSON is a subset of JavaScript's literal syntax.)
(I've also added an echo there; I'm not much of a PHP-head, so remove it if it's not needed, but you're not using short-tags, so...)
Escape the single quotes in the PHP output! :)
Replace the ' with \'
Obviously you need to ensure you are escaping quotes within strings or the Javascript will break. A simple solution would be to use double-quotes inside the string, and use single-quotes to delimit the string.
'<div id="gaugearray8">'

Categories