htmlspecialchars和ENT_QUOTES无效?

9

基本上,从MySQL数据库中显示数据时,我有一个 htmlspecialchars() 函数,可以将单引号和双引号转换为安全实体。但是,我遇到的问题是在查看源代码时,它只转换了 < > & ,而我还需要它转换单引号和双引号。

//sanitize data from db before displaying on webpage
function htmlsan($htmlsanitize){
    return $htmlsanitize = htmlspecialchars($htmlsanitize, ENT_QUOTES, 'UTF-8');
}

那么当我想使用某个示例时,我会这样做:

htmlsan($row['comment']);

有人能告诉我为什么它不能转换单引号和双引号吗?

更新

奇怪的是,在电子邮件中对评论使用了htmlsan(),当我查看电子邮件的源代码时,它会将它们转换,但在网页上显示时似乎不会从数据库转换单/双引号。我的数据库排序规则也设置为utf8_general_ci,并声明我在数据库连接等方面使用了utf8。


1
这是一个打字错误吗:htmlan($row['comment']);?如果是的话,你可能在调用不同的函数。 - Shakti Singh
嗨,不是打错了,我刚刚双重检查过了,在发布这个问题时我打错了,抱歉,但实际的代码中没有打错。 - PHPLOVER
1
仅仅调用 htmlsan($row['comment']); 不会影响你代码中的任何变量。 - Your Common Sense
嗨Col,你的意思是什么?我认为我上面展示的例子应该可以工作,在< > &上确实可以,但在单引号/双引号上不行。 - PHPLOVER
3
伙计,你急需发布一个确切完整的例子,而不是另一段空洞的胡言乱语。 - Your Common Sense
5个回答

11

你是如何对其进行精确测试的?

<?php

//sanitize data from db before displaying on webpage
function htmlsan($htmlsanitize){
    return $htmlsanitize = htmlspecialchars($htmlsanitize, ENT_QUOTES, 'UTF-8');
}

var_dump(htmlsan('<>\'"'));

... 打印:

string(20) "&lt;&gt;&#039;&quot;"

我猜测你输入的字符串来自于微软Word并包含排版引号:

var_dump(htmlsan('“foo”')); // string(9) "“foo”" 

如果出于任何原因确实需要将它们进行转换,那么您需要使用htmlentities()而不是htmlspecialchars()

var_dump(htmlentities('“foo”', ENT_QUOTES, 'UTF-8')); // string(17) "&ldquo;foo&rdquo;"

更新 #1

好的,现在是进行一些适当的测试的时候了。在你的comment数据库字段中输入一个单引号('),并且在检索它时运行以下代码:

var_dump(bin2hex("'"));
var_dump(htmlspecialchars("'", ENT_QUOTES, 'UTF-8'));
var_dump(bin2hex($row['comment']));
var_dump(htmlspecialchars($row['comment'], ENT_QUOTES, 'UTF-8'));

应该打印出这个:

string(2) "27"
string(6) "&#039;"
string(2) "27"
string(6) "&#039;"

请更新您的问题并确认是否运行此测试并获得相同或不同的输出。

更新 #2

请仔细查看您声称获取的输出:

string(6) "'"

这不是一个具有6个字符的字符串。您看到的不是真正的输出,而是由浏览器渲染后的输出。我相信您获得了预期的结果,即 string(6) "&#039;"。如果您在Web浏览器中渲染&#039;,它将变成'。使用浏览器的查看源代码菜单查看真正的输出。


建议更新问题,因为您可以格式化输出以使其可读,您可以发布您运行的确切代码和相关信息对每个人都有用。不过没关系,看看我的第二次更新。 - Álvaro González
嗨,Alvaro。查看源代码显示相同的内容。无论如何,我还是查看了源代码,因为浏览器会将其显示为其意图,但查看源代码会以其安全形式显示它。 string(6) "'" string(2) "27" string(6) "'" string(2) "27" 谢谢。 - PHPLOVER
1
嗨,阿尔瓦罗,请阅读上面的评论。我刚刚注意到它实际上是在工作的:O原因是我使用FireFox中的Firebug查看源代码,而Firebug不会像在浏览器菜单上单击“查看源代码”那样显示它。我非常抱歉,但以前不知道Firebug是如何显示网页的,我以为它会像你通过浏览器本身查看源代码一样显示它。 - PHPLOVER
1
嗯,没错,Firebug的HTML标签解码了HTML实体(我之前也没注意到)。不管怎样,我很高兴你解决了问题。至少你学到了一些调试技巧 :) - Álvaro González
更新2很有帮助。感谢指出这一点。我也没有注意到它。 - Rich
显示剩余5条评论

4
当你使用Firebug查看源代码时,Firebug显示的是网页浏览器显示的样子,我原以为它会像在浏览器菜单栏中点击“查看源代码”一样显示源代码。这让我头疼不已,但我会记住这个问题的。感谢大家宝贵的时间和意见。

遇到了同样的问题。通过FireFox查看源代码,使用htmlentities($str,ENT_QUOTES, "UTF-8");时单引号显示为单引号,完全无效。如果您安装了Chris Pedrick的Web Developer扩展,并通过该扩展查看源代码,则会看到单引号显示为&#039;。故事的寓意是,使用未经过HTML净化的原始视图源代码,以便您可以确定一切正常工作。 - Fiasco Labs

1

我有同样的问题。我的数据库使用utf-8_unicode_ci,我的html字符集也是utf-8,但是htmlentities只转换了除引号以外的所有内容。我认为在数据库和html中具有相同的字符集应该没问题,但实际上并不是这样。所以我将html的字符集更改为iso-8859-1,然后它就可以正常工作了。我不知道为什么,但它确实起作用了。我的数据库仍然使用utf-8_unicode_ci。


这就是我遇到的问题。谢谢。 - Blake Frederick

1

不确定这是否会有任何影响,但您是否尝试过删除$htmlsanitize

function htmlsan($htmlsanitize){
    return htmlspecialchars($htmlsanitize, ENT_QUOTES, 'UTF-8');
}

嗨,马特,感谢您的回复,非常感激。出于某种原因,它仍然无法转换单引号和双引号,但它可以转换< > &。 - PHPLOVER

0

使用

htmlentities($htmlsin, ENT_QUOTES, 'UTF-8');

或者

mb_convert_encoding($htmlsan, "HTML-ENTITIES", "UTF-8");

可能会做你想要的事情。


你好,第一种选项是我已经拥有的,而第二种选项则不会将可能存在的恶意标签(如JavaScript等)转换为安全实体,例如< >。 - PHPLOVER

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接