Using innerhtml to write html with A LOT of quotes - php
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 of External Revenue"],"KpiName":["revcontrubionkpi"],"ValuetoPrint":[0.0011217599587192],"ValueNow":[19],"ValueCompare":[1693767],"Target":["8"],"KpiUnits":["Pounds"],"PercentCompare":[0.0011217599587192]}]) onmouseover=TopLevelLabel({"NumberSelected":1,"Description":["Contribution of External Revenue"],"GroupDescription":"Ancillary Service Performance"}) 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 Cost per Service Km","Revenue per Service Km","Total Cost per Service Km","Claims Cost per Vehicle","Claims Cost per Driver","Number of Claims Lodged per 100,000km","Overheads Cost per Service Km"],"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 per Km","Pounds per Km","Pounds per Km","Pounds per Vehicle","Pounds per Driver","Claims","Pounds a km"],"PercentCompare":[110.47252736225,5.6435200058102,5.434671444334,0.35610369406272,0.35829645079956,12.666666666667,18.054408207469]}]) onmouseover=TopLevelLabel({"NumberSelected":7,"Description":["Operating Cost per Service Km","Revenue per Service Km","Total Cost per Service Km","Claims Cost per Vehicle","Claims Cost per Driver","Number of Claims Lodged per 100,000km","Overheads Cost per Service Km"],"GroupDescription":"Core Service Performance"}) 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 Expenditure per Passenger Journey","Cost Per Headcount"],"KpiName":["revexperjourneykpi","coststaffkpi"],"ValuetoPrint":[19.044041148259,0.41451199641943],"ValueNow":[1,16.578947368421],"ValueCompare":[5.2509863437855,3999.6302909519],"Target":["8","8"],"KpiUnits":["Pounds per Journey","Pounds per Staff"],"PercentCompare":[19.044041148259,0.41451199641943]}]) onmouseover=TopLevelLabel({"NumberSelected":2,"Description":["Revenue Expenditure per Passenger Journey","Cost Per Headcount"],"GroupDescription":"Resource Optimisation"}) 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 of External Revenue"],"KpiName":["revcontrubionkpi"],"ValuetoPrint":[0.0011217599587192],"ValueNow":[19],"ValueCompare":[1693767],"Target":["8"],"KpiUnits":["Pounds"],"PercentCompare":[0.0011217599587192]}]) onmouseover=TopLevelLabel({"NumberSelected":1,"Description":["Contribution of External Revenue"],"GroupDescription":"Ancillary Service Performance"}) 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 Cost per Service Km","Revenue per Service Km","Total Cost per Service Km","Claims Cost per Vehicle","Claims Cost per Driver","Number of Claims Lodged per 100,000km","Overheads Cost per Service Km"],"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 per Km","Pounds per Km","Pounds per Km","Pounds per Vehicle","Pounds per Driver","Claims","Pounds a km"],"PercentCompare":[110.47252736225,5.6435200058102,5.434671444334,0.35610369406272,0.35829645079956,12.666666666667,18.054408207469]}]) onmouseover=TopLevelLabel({"NumberSelected":7,"Description":["Operating Cost per Service Km","Revenue per Service Km","Total Cost per Service Km","Claims Cost per Vehicle","Claims Cost per Driver","Number of Claims Lodged per 100,000km","Overheads Cost per Service Km"],"GroupDescription":"Core Service Performance"}) 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 Expenditure per Passenger Journey","Cost Per Headcount"],"KpiName":["revexperjourneykpi","coststaffkpi"],"ValuetoPrint":[19.044041148259,0.41451199641943],"ValueNow":[1,16.578947368421],"ValueCompare":[5.2509863437855,3999.6302909519],"Target":["8","8"],"KpiUnits":["Pounds per Journey","Pounds per Staff"],"PercentCompare":[19.044041148259,0.41451199641943]}]) onmouseover=TopLevelLabel({"NumberSelected":2,"Description":["Revenue Expenditure per Passenger Journey","Cost Per Headcount"],"GroupDescription":"Resource Optimisation"}) 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">'
Related
Will php's json_encode() always use double quotes as string delimiter?
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));
Escaping string before assigning to innerHTML echoed by PHP
I'm encountering a problem involving escaping character that I think it's not simple at all. If this is done in javascript, nothing to say but the context is using echo command (in PHP) to write javascript code like this: echo "<script>document.getElementById('spanID').innerHTML=\"$x\"</script>"; $x is a variable in PHP environment, which can contain both single and double quotes. What I do here is: 1. Keep the $x not change, and if $x contains any double quote, the above code won't work, the text echoed may look like: <script>document.getElementById('spanID').innerHTML="leftside"rightside"</script>; I supposed $x = leftside"rightside, and you can see it surely won't work. Escape the double quotes in $x (change all " to "), then the text echoed may look like this: document.getElementById('spanID').innerHTML="leftside"rightside"; The " won't be converted to " when it is assigned to innerHTML attribute of a Span (for e.g), so instead of my want, the innerHTML of my SPAN should be leftside"rightside, it will be leftside"rightside. If I change the " to ' in the original echo, like this: echo "<script>document.getElementById('spanID').innerHTML='$x'</script>"; It is the same because $x here can contain both single and double quotes. I don't find out any other ways to escape quotes in this case. Could you please help me out? Thanks!
You need to put between the quotes a string that is a valid string of JavaScript containing valid (and safe) HTML. Your best option is to not use innerHTML and instead use document.createTextNode which means you only need to slash-escape the content. Otherwise, you need to HTML escape, then slash escape the content. For correctness, your slash-escaping function should escape at least double-quotes, backslashes, and all JavaScript newlines (U+A, U+D, U+2028, U+2029). I believe PHP's addslashes does not handle U+2028 or U+2029 by default but How to escape string from PHP for javascript? has some alternatives. To put it all together: $x_escaped = json_encode($x, JSON_HEX_TAG); echo "<script>document.getElementById('spanID').appendChild(document.createTextNode($x_escaped))</script>" should do it. The JSON_HEX_TAG makes sure that $x_escaped will not contain </script> or any other content that prematurely ends your script tag. </script> will instead become \u003c/script\u003e.
PHP: literal \n rather than new line
I have a php var which, when echoed, writes a JS function into the source of a page. The function loops through a CSV and so it has the following line within it: $str="var lines = data.split('\n');"; At the present time, when echoed, I get this 'correct' JS written into the source: var lines = data.split(' '); Instead, I want to echo the literal string \n into the source of the page. Can anyone point me in the right direction? Thanks.
Escape the slash. "\\n" So that it is treated as a slash instead of an escape character.
Try this: $str="var lines = data.split('\\n');";
you can escape \ like this: \\. But I would put the whole JS functionality into a .js file, include that from the generated HTML, and call the specific function when needed. And generate a minimalistic js code, like var config = {....} if I have to communicate some page related information. You almost never need dynamically generated JS code. It's a lot harder to read and you're wasting CPU and network bandwidth...
Either the solutions in the earlier answers, or invert the quotes by using single quotes as the PHP string delimiter: $str='var lines = data.split("\n");'; Or escape the inner quotes, if you want to keep single quotes for javascript as well when using single quotes as the PHP string delimiter. $str='var lines = data.split(\'\n\');'; See the docs on quoted strings in PHP as well about how single quoted strings and double quoted strings behave differently.
How can I write a square bracket to a text file in php?
I'm trying to write a php script that will generate a variety of new php pages, but I'm finding that I'm unable to write a square bracket out. When I escape a square bracket in the same way as other characters (ie [ ) the leading \ is written to the new page, which results in code that doesnt work: echo $row\['Value'\]; When I do not escape the bracket, the page fails, and the same thing happens when I try and substitute asc(91). I have seen other examples that use code like $row->Value, but I tried that and it didn't work. If anyone can help me output a square bracket, or knows of another method by which I can fetch a value from a row without using one at all, I'd be very grateful
Your echo would appear as an array reference to PHP. Try this: echo $row, "['Value'];" assuming that you want the value of $row to be output, and not the literal text $row. If you want the literal text, (e.g. you're trying to build a PHP script on the fly), then either of these should do the trick: echo '$row[\'Value\'];'; echo "\$row['Value'];";
How about this: echo sprintf("\$row['%s']", $value); // either scenario echo sprintf("%s['Value']", $row); Keep in mind that PHP automatically parses double quote strings ("), and tries to find variabels within. So, the bracket is probably not the issue, the $ variable prefix (coupled with the parser) probably is.
There are a couple other answers that work but I want to elaborate: The "echo" construct can take a variable or a string. You can't echo a string to the screen in the same way that you do a variable. For example: echo hello; will not behave as you might think. You need to include it in quotes such as echo "hello"; You can also use single quotes. Single quotes and double quotes behave differently. For example: $foo = "bar"; echo $foo; echo "$foo"; echo '$foo'; The first will echo "bar", the second will also echo "bar" because PHP looks for variables in double quotes strings. The third will echo '$foo' because PHP does not try to do variable substitution in a single quoted string. So you can do (as #mark-b said): echo "\$row['Value']"; or echo '$row[\'Value\']'; Now, that $row->value syntax that you saw, is object notation. It is assuming that $row is an object and not an array. Objects are a whole other ballgame.
You're talking about code generation in your question, so I expect you also want to output the 'echo' statement in the generated code. Assuming you want to save the output into a file so it can be easily executed, you want to use something like fwrite or file_put_contents, I expect. You need to think in terms of strings, which can be a bit tricky when you're seeing code. Something like this should work: fwrite($fp, 'echo $row[\'Value\'];'."\n"); Note how the single and double quotes work. \n is resolved to a newline, but anything in the single quotes is treated as a string and is printed as is, apart from \', which should print a literal single quote in the output file. Hope this helps.
Escape brackets on php for javascript
For example i've a php script with this content: <?php $msg = addslashes("I'm a message. The what happened >:("); echo "<script>alert($msg); return false;</script>"; ?> But the alert get broken by the last "(". How can i solve this?
You should enclose alert parameter with quotes: echo "<script>alert('$msg'); return false;</script>"; What your code outputs to the browser was: <script>alert(The what happened >:(); return false;</script> which is not a valid javascript, after putting the quotes, it becomes: <script>alert('The what happened >:('); return false;</script> which is valid javascript.
You need to put it in a JavaScript string, otherwise it gets interpreted like this, which is meaningless and causes an error: <script>alert(The what happened >:(); return false;</script> Notice the single quotes in the alert() call which denote a JavaScript string (double quotes work too): <?php $msg = "The what happened >:("; echo "<script>alert('$msg'); return false;</script>"; ?> It is also a good idea to escape the content inside to mitigate XSS, using htmlspecialchars().
The other answers are along the right lines, but it is not sufficient to just put quotes around the string, if it can be any arbitrary string. If the string itself contains a quote, backslash, or newline, that will break the JavaScript string literal. If the string contains </script (or just </ in some cases) that will break the <script> block. In either case, if user-supplied input is involved, that gives you a big old cross-site-scripting security hole. Whilst you may not need it for this specific value of $msg, it's a good idea to get used to JS-string-literal-escaping any text you output into a JS string. Whilst you can do this manually by adding backslashes, it's generally much easier to just use the built-in JSON encoder, which will work for other types like arrays and objects as well as strings. <script type="text/javascript"> alert(<?php echo json_encode($msg); ?>); return false; // huh? return, in a <script> block?? </script>
alert() accepts a string argument; you must enclose the text you're passing to it in quotes (either single or double) and insure that any matching quotes within the string are escaped by backslashes. In your case single quotes would suffice: echo "<script>alert('$msg'); return false;</script>";
Depending on the context, you might also just do: <?php $msg = "The what happened >:("; ?> <script>alert("<?php echo $msg ?>"); return false;</script> If there is no need to echo HTML or JavaScript code, then don't do it. It is easier to maintain .