-1

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)

segon
  • 273
  • 1
  • 4
  • 16
  • tip: open and close stuff with single quotes - it's faster :) – treyBake Jul 28 '17 at 13:18
  • 1
    Escape them with backticks. Btw, its not really good practice to store the whole HTML-img tag in a variable. Instead, you should only save the image NAME in a variable and then include this var in your HTML code. Like `` – Twinfriends Jul 28 '17 at 13:18
  • `$fotoTag1 = "\"don't\"";` – GrumpyCrouton Jul 28 '17 at 13:18
  • @litelite — \ is not character with any special meaning in HTML. Putting it in an HTML attribute value just means \ – Quentin Jul 28 '17 at 13:19
  • @Quetin Oh right, wrong escape – litelite Jul 28 '17 at 13:20
  • Possible duplicate of [How to escape quotes/apostrophe in php?](https://stackoverflow.com/questions/9848346/how-to-escape-quotes-apostrophe-in-php) – GrumpyCrouton Jul 28 '17 at 13:20
  • @Twinfriends You're example would still need the whole thing to be inside a double quoted php-string (or the `{$fotoTag1}` would be outputted literally). :) I think you mean: `` – M. Eriksson Jul 28 '17 at 13:20
  • @GrumpyCrouton Woops, you are right – RiggsFolly Jul 28 '17 at 13:23
  • @ThisGuyHasTwoThumbs Even though your comment actually is true, I dare you to show me a real world example where the difference is even remotely noticeable (and no, you're not allowed to run PHP on an old C=64 or Texas Instruments calculator from the mid 90's) :-) – M. Eriksson Jul 28 '17 at 13:32
  • @MagnusEriksson well in small doses the difference won't be noticeable but with large data I think it makes a noticeable difference - wil try and find something for ya :) – treyBake Jul 28 '17 at 13:33
  • $fotoTag1 = 'don't'; echo $fotoTag1; – Pratik Soni Jul 28 '17 at 13:37
  • Why negative points? my question is different than the others. I made my search – segon Jul 28 '17 at 14:13

6 Answers6

2

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.

axiac
  • 68,258
  • 9
  • 99
  • 134
2
$fotoTag2 = "<img src=\"don't.svg\" alt=\"don't\">";
echo $fotoTag2;
Lesiuk Alexey
  • 237
  • 1
  • 2
  • 7
1
$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 (&#39;);

<img src='don&apos;t.svg' alt='don&#39;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).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
0

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.

yanman1234
  • 1,009
  • 9
  • 27
  • "You had the right idea using htmlspecialchars()" — They didn't. It's the data you put in the attribute values that needs to be encoded, not the complete string of HTML. – Quentin Jul 28 '17 at 13:35
  • They had the correct idea with using that function, but yes the execution was incorrect and has been noted. – yanman1234 Jul 28 '17 at 13:39
0

Try this, it's working:

$fotoTag1 = '<img src="'.htmlspecialchars("don't.svg").'" 
alt="'.htmlspecialchars("don't").'">';
echo $fotoTag1;
-1

You should use the html ascii codes, so for your example:

$fotoTag2 = "<img src='don&#39;t.svg' alt='don&#39;t'>";

Since ' is the ascii code for single quote.

Kyle Becker
  • 1,360
  • 12
  • 20