Quotes in a php var - php

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 (&apos;) or one of the numeric references to the position of the character in unicode (');
<img src='don&apos;t.svg' alt='don't'>
Beware: &apos; 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.

Related

PHP echo returning blank value

So I am trying to link using data I got from a function but it keeps giving me a blank value for ID. Here's my code for what I'm trying to print
<h3 style="text-align: center;">Seller: <?php $sellername =
getNameFromListingID(); $id = getIDByUsername($sellername); echo "".$sellername."";?></h3>
The functions work properly, I have tried printing both of them and it works. They're in a file called getinfo.php, which I have
Include 'getinfo.php';
At the top of my document.
The link with the name works but I always get seller.php?id=, with no value after. Any clue as to why?
You're ending the href attribute too early.
<a href=\"seller.php?id=".$id."\">
This will put the $id inside the href attribute, where it belongs.
Use single quotes in PHP, it's a good practice to get into, and it's also slightly (a teeny tiny bit) faster for PHP to process. Why? Because, when you use double quotes, you're telling PHP that your string contains variables that may need to be evaluated.
So in truth, you don't even need the quotes around variables here.
echo "$sellername";
But doing it like this would be following a best practice.
And now you don't need to escape \" double quotes that HTML uses.
echo ''.$sellername.'';
Caution: It's also a very good idea to escape special characters in anything you're outputting into HTML markup. That avoids the potential for an XSS vulnerability. See: htmlspecialchars()
echo ''.htmlspecialchars($sellername).'';

Add php variable as a part of a link address?

I'm trying to add a variable as a part of a link, but I haven't could do it.
<?php
$fname=$data_array["firstname"];
echo '<a class="pin-button" href="https://myweb.com/description=$fname&editable=false&success_url=http%3A%2F%myweb.com%2Fsuccess"><img src="http://myweb.com/images/button.png" width="120"></a>';
?>
the link works perfect, but I need to add the variable after description=$fname
Thanks a lot!
1: $variables don't work inside single quotes, instead of
echo '<a href="$path">'`
try
echo "<a href='$path'>"
2: If you wish to use single quotes you can use concatenation instead:
echo '<a href="'.$path.'">'
3: In either case, you should be escaping your strings when printing them inside HTML:
echo "<a href='".htmlspecialchars($path, ENT_QUOTES)."'>"
This prevents characters (such as quotes and less-than signs) having unintended effects, and prevents exploits by maliciously crafted data.

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.

Proper way to pass complex variables to javascript through HTML

I was trying to get away from using PHP's htmlentities and here's where I stopped:
<?php
echo '<img ... onclick="MP.view(\''.$i->name.'\') />';
?>
But then I thought, instead of doing replaces and checks for special characters, I'll just JSON the entire object.
<?php
echo '<img ... onclick="MP.view('.json_encode($i).') />';
?>
And this provided a much undesired result putting in a ton of double quotation marks.
So how should I do this? Should I assign a numerical unique id to every image and just pass the id, and then look up the rest of the data from a JS array?
The correct approach in such cases would be:
htmlspecialchars(json_encode($var), ENT_QUOTES, "UTF-8")
htmlspecialchars turns any double quotes into the proper HTML escapes, making the resulting string suitable for most attributes. The ENT_QUOTES parameter also takes care of single quotes; but you probably don't need that in your example.
It would take a whole lot less escaping (and fewer bytes) to pass the data something like this:
echo '<script>var myObj = '.json_encode($i).'</script>';
Then, your code could look more like this:
echo '<img ... onclick="MP.view(myObj)" />';

single quote in file name - javascript,php

How can I deal with a quote in data that has to be there?
This javascript statement works fine until city name is "ST JOHN'S".
We are not able to change the change the city name in database -or- use a more reliable key.
$('#map_output').html('<p><img src="img/map/<?=$CITY_OUT?>_map.PNG" width="600"></p>')
Use htmlspecialchars().
EDIT: you use it (sorta) like json_encode:
<?=htmlspecialchars($CITY_OUT, ENT_QUOTES)?>
But htmlspecialchars is more semantic - json_encode is about generating JSON (internal, data representation), not about presentation.
Nick Craver is right though - it'll also work.
Edit: need ENT_QUOTES for rendering " ' " correctly...
You can use json_encode() to escape the quote, like this:
<?=json_encode($CITY_OUT)?>
There are three levels of encoding needed:
You're creating a URL, so you need to URL-encode it:
$url = rawurlencode('img/map/'.$CITY_OUT.'_map.PNG');
You're creating an HTML attribute, so you need to HTML-encode it:
$html = '<p><img src="'.htmlspecialchars($url).'" width="600"></p>';
That second step may not make a big difference, since you're not likely to have ', ", &, <, or > in your URL. But if you want to be strictly correct, you should encode all HTML attributes. It's a good habit to get into, so you can handle all special characters.
Finally, you're creating a JavaScript value, so you need to JSON-encode it:
$('#map_output').html(<?= json_encode($html) ?>)
(edited to add JSON-encoding)
In my quick tests, neither of the two answers worked:
<?php
$string = "ST JOHN'S";
$json = json_encode($string);
$html = htmlspecialchars($string);
$escape = str_replace("'", "\'", $string);
?>
<script type="text/javascript">
alert('<?php echo $escape?>');
alert('<?php echo $html?>');
alert('<?php echo $json?>');
</script>
The only test which did not produce a javascript error was my usage of str_replace to actually escape the single quote.
"rawurlencode" is what you need to ensure the characters in the URL are interpreted the same on the "img/map/..." request the same way they are in this PHP script.
Incidentally, "rawurlencode" safely escapes all of the characters you need to worry about in XSS injections.
<?php
$string = "ST JOHN'S";
$json = json_encode($string);
$html = htmlspecialchars($string, ENT_QUOTES);
$htmlent = htmlentities($string, ENT_QUOTES);
$escape = str_replace("'", "\'", $string);
$urlenc = rawurlencode($string);
?>
<script type="text/javascript">
alert('<?php echo $html; ?>');
alert('<?php echo $htmlent; ?>');
alert('<?php echo $urlenc; ?>');
</script>
You've said that none of the solutions given so far have worked for you, but I think actually they're fine (at least some of them). Let me demonstrate:
Here are the examples you listed:
$json:
<img src="img/map/"ST JOHN'S"_map.PNG"/ width="600">
$html:
<img src="img/map/ST JOHN'S_map.PNG"/ width="600">
$htmlent:
<img src="img/map/ST JOHN's_map.PNG"/ width="600">
$escape:
<img src="img/map/ST JOHN\'S_map.PNG"/ width="600">
$urlenc:
<img src="img/map/ST%20JOHN%27S_map.PNG"/ width="600">
I don't see any problem with any of these (except the JSON one, which I'll explain in a moment).
And I've just tried all these examples, trying to simulate your scenario as closely as possible (even down to using the same file name).... All of them loaded the graphic correctly, again except the JSON example.
The JSON example needs a minor tweak to get it working, but it also does escape the string in a workable way. To get it working you need to take into account that JSON produces a fully-quoted Javasscript string rather than just escaping it as the others do, so you'd modify the output to close the quotes and add the strings together, like so:
$('#map_output').html('<p><img src="img/map/"+<?=$json?>+"_map.PNG"/ width="600"></p>');
The other solutions don't need this. They all work as is. As I say, I tried them, and they all loaded the graphic into the page.
In the context, all three mechanisms (escaping \', entities &#039 and URL encoding %27) are valid:
Escaping works because you're in the context of Javascript, so the backslash gets dealt with by Javascript and the final generated HTML that gets inserted into the page won't contain it.
Entities work because HTML translates entities into the mapped character, so &#039 in a HTML page is the same as a single quote, even within an attribute value as in this case.
URL Encoding works because browsers translate them when they load a URL.
I would suggest URL encoding is the correct solution in this case, since this is being used for a URL. The reason for that is that while all the solutions work for the given example, if you have any examples that contain a question mark or an ampersand (&) or a few other reserved characters, then URL encoding will be the only solution that will work in these cases. On the other hand, if you're displaying the output in your HTML page in another context, then entities are the way to go. And if it is going to be used just within Javascript, then JSON is the answer.
But you say none of them did the trick. My question is: Did you actually try them? Did you run the code and the graphic failed to load? It did for me. On the other hand, if they did work, but still don't "do the trick", then what is it you actually want?
My guess is that what you actually mean is that you want to end up with a simple quote character there, but have it magically work. That can't happen; the quote has to be escaped somehow or other in order for it to work, but they user will never see the escaped version, so there's no need to worry about it.
In fact, you should be escaping or encoding all the strings you input or output, so that invalid characters do work. Otherwise Mr O'Brien is going to have trouble entering his name into your site, and if he manages it, you'll have trouble displaying it afterward.
Unfortunately none of the above solutions did the trick.
<?
$string = "ST JOHN'S";
$json = json_encode($string);
$html = htmlspecialchars($string, ENT_QUOTES);
$htmlent = htmlentities($string, ENT_QUOTES);
$escape = str_replace("'", "\'", $string);
$urlenc = rawurlencode($string);
?>
$json:
<img src="img/map/<?=$json?>_map.PNG"/ width="600">
$html:
<img src="img/map/<?=$html?>_map.PNG"/ width="600">
$htmlent:
<img src="img/map/<?=$htmlent?>_map.PNG"/ width="600">
$escape:
<img src="img/map/<?=$escape?>_map.PNG"/ width="600">
$urlenc:
<img src="img/map/<?=$urlenc?>_map.PNG"/ width="600">
output:
$json:
<img src="img/map/"ST JOHN'S"_map.PNG"/ width="600">
$html:
<img src="img/map/ST JOHN'S_map.PNG"/ width="600">
$htmlent:
<img src="img/map/ST JOHN's_map.PNG"/ width="600">
$escape:
<img src="img/map/ST JOHN\'S_map.PNG"/ width="600">
$urlenc:
<img src="img/map/ST%20JOHN%27S_map.PNG"/ width="600">

Categories