RE: [PHP] Getting knotted with quotes encoding - (one possible solution)
| From: | Arno Kuhl | Date: | Tue, 13 Mar 2012 14:35:44 +0000 |
| Subject: | RE: [PHP] Getting knotted with quotes encoding - (one possible solution) | ||
| Groups: | php.general | ||
| Request: | Send a blank email to php-general+get-317003@lists.php.net to get a copy of this message | ||
From: Ashley Sheridan [mailto:ash@ashleysheridan.co.uk]
Sent: 13 March 2012 03:25 PM
To: arno@dotcontent.net; php-general@lists.php.net
Subject: Re: [PHP] Getting knotted with quotes encoding
Arno Kuhl <arno@dotcontent.net> wrote:
>I've been battling with quotes encoding when outputting javascript with
>php.
>It can't be unique, so I'm hoping someone has a working solution
>they're willing to share.
>
>The following works perfectly as long as there aren't any single quotes
>in the link text:
> echo "<span onclick=\"insertLink('$sUrl','$sTitle')\"
>class='linkSel'>$sTitle</span>";
>
>if $sTitle has the value What's new it outputs:
> <span onclick="insertLink('article/whats-new.html','What's
>new')" class='linkSel'>What's new</span>
>
>It displays fine, but javascript complains with:
> Expected ')' linkmanager.php Line:525 Char:63
>
>
>So I fix this by swapping the double and single quotes around:
> echo "<span onclick='insertLink(\"$sUrl\",\"$sTitle\")'
>class='linkSel'>$sTitle</span>";
>
>Now for that specific link it outputs:
> <span onclick='insertLink("article/whats-new.html","What's
>new")' class='linkSel'>What's new</span> And javascript is
>happy.
>
>But elsewhere there's a link Fred "Buster" Cox and it outputs:
> <span onclick='insertLink("article/fred-buster-cox.html","Fred
>"Buster" Cox")' class='linkSel'>Fred
>"Buster"
>Cox</span>
>
>Again it displays fine, but javascript complains with:
> Expected ')' linkmanager.php Line:743 Char:77
>
>
>So it looks like I can't have links that include single quotes and
>double quotes, only one or the other.
>
>One work-around I thought of was to convert any link texts that
>included double quotes into single quotes when the content is posted,
>and it would then be displayed with single quotes even though the user
>entered double quotes. It's far from ideal but it would work, though I
>can think of a few situations where it would be quite confusing to the
>reader. Are there any other solutions that would allow both types of
>quotes without any conversions?
>
>Cheers
>Arno
>
>
>--
You aren't escaping the quotes correctly when they go into your output. You're escaping
them for html not javascript. Javascript (like php) escapes single quotes inside a single quote
string with a back slash.
Thanks,
Ash
http://ashleysheridan.co.uk
---------
Thanks for that Ashley.
You're right about the encoding.
I had a line prior to that:
$sTitle = htmlentities($title, ENT_QUOTES, 'ISO-8859-1', FALSE);
Which encoded the quotes.
I couldn't find anything so made a function, which might be useful for others.
It’s a first shot, I'm sure there are ways to improve performance.
I also changed the encoding to exclude single quotes.
(I'm sure the indenting will get screwed up in the mail)
$sTitle = fixSingleQuotes(htmlentities($title, ENT_COMPAT, 'ISO-8859-1', FALSE));
.....
////////////////////////////////////////////////////////////////////////////////
// convert single quotes to curly quotes, xml compliant
// assumes apostrophes must be between 2 alpha chars
// and any other ' is a single quote
// ‘ = left single quote
// ’ = right single quote and apostrophe
function fixSingleQuotes($sText)
{
if (strpos($sText, "'") !== FALSE) {
// there are quotes to convert
$bOpenQuote = FALSE;
$arrAlpha = explode(' ', "a b c d e f g h i j k l m n o p q r s t u v w x y z A B C
D E F G H I J K L M N O P Q R S T U V W X Y Z");
$arrText = str_split($sText);
while (($pos = strpos($sText, "'")) !== FALSE) {
if ($pos == 0) {
// must be an open quote in first pos
$sText = "‘".substr($sText, 1);
$bOpenQuote = TRUE;
} else {
if (in_array($arrText[$pos-1], $arrAlpha) AND in_array($arrText[$pos+1], $arrAlpha)) {
// apostrophe
$quote = "’";
} else {
// quote
if (!$bOpenQuote) {
$quote = "‘";
$bOpenQuote = TRUE;
} else {
$quote = "’";
$bOpenQuote = FALSE;
}
}
$sText = substr($sText, 0, $pos).$quote.substr($sText, $pos+1);
}
}
}
return ($sText);
} //fixSingleQuotes()
Cheers
Arno