I am quite new in php. I have to store a img tag in a var. I think this is ok:
$fotoTag1 = "<img src='42.png'
alt='text alt'>";
But the problem comes if there is a single quote in the name of the photo or in the alt?. For intance, don't
What I have tried:
$fotoTag1 = "<img src='don't.svg' alt='don't>'";
echo htmlspecialchars ($fotoTag1);
echo addslashes($fotoTag1);
$fotoTag2 = "<img src='don\'t.svg' alt='don\'t'>";
echo $fotoTag2;
(This is a simplified example but the url and alt comes from a sql database and of course, I cannot change the text manually. I need a general solution)
Use htmlspecialchars() to properly encode the text fragments you use to build the HTML fragment, not the HTML you built:
$fotoTag1 = '<img src="'.htmlspecialchars("don't.svg").'" alt="'.htmlspecialchars("don't").'">';
Or, to be more clear:
// Wrapped for clarity
$fotoTag1 = sprintf(
'<img src="%s" alt="%s">',
htmlspecialchars("don't.svg"),
htmlspecialchars("don't")
);
Read about sprintf() and the different ways to specify a string in PHP.
addslashes() doesn't help when you build HTML content. As a side note, it is an obsolete function that doesn't have many usages nowadays.
$fotoTag2 = "<img src=\"don't.svg\" alt=\"don't\">";
echo $fotoTag2;
$fotoTag1 = "<img src='don't.svg' alt='don't>'";
Your problem here has nothing to do with PHP.
You have an HTML attribute value delimited with apostrophe characters and you want to use an apostrophe inside that value.
When you want to represent a character with special meaning in HTML as that raw character, you can use a character reference.
This can be a named entity (') or one of the numeric references to the position of the character in unicode (');
<img src='don't.svg' alt='don't'>
Beware: ' was added to HTML relatively late. Old versions of IE do not support it.
Alternatively you could change your HTML so you use double quotes to delimit the data:
<img src="don't.svg" alt="don't">
This would introduce a PHP problem because you are using them to delimit the string literal.
In this case you would need to escape the data for PHP, which you do with a backslash character.
$fotoTag1 = "<img src=\"don't.svg\" alt=\"don't\">";
Alternatively, you could use some other form of string generation, such as HEREDOC.
$fotoTag1 = <<<END
<img src="don't.svg" alt="don't">
END;
As a rule of thumb, it is better to avoid storing HTML in variables in the first place.
When you want to output data, just switch to output mode:
?>
<img src="don't.svg" alt="don't">
<?php
You can always drop back into PHP mode if you need a variable.
$src = "don't.svg";
$alt = "don't";
?>
<img src="<?php echo htmlspecialchars($src); ?>" alt="<?php echo htmlspecialchars($alt); ?>">
<?php
(Note that for the characters involved, htmlspecialchars isn't needed in this example, but it does protect you when dealing with programmatically acquired data that you can't guarantee to be HTML safe).
You had the right idea using htmlspecialchars(), the issue with this specific example is that function does not escape ' by default. You need to add the flag ENT_QUOTES to escape single quotes with htmlspecialchars().
You should also be applying this function just to strings you wish to escape, not the entire html line. This could, and most likely will in most cases, cause unintended side effects of escaping characters you didn't want escaped.
Try this, it's working:
$fotoTag1 = '<img src="'.htmlspecialchars("don't.svg").'"
alt="'.htmlspecialchars("don't").'">';
echo $fotoTag1;
You should use the html ascii codes, so for your example:
$fotoTag2 = "<img src='don't.svg' alt='don't'>";
Since ' is the ascii code for single quote.
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.
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">'
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 .