首页 > 解决方案 > 为什么 filter_var() 对引号的编码与 htmlentities() 不同?

问题描述

为什么 filter_var() 的 FILTER_SANITIZE_STRING 过滤器将单引号编码为'和双引号编码为,"而 htmlentities() 将单引号编码为'和双引号编码为"

代码示例:

<?php
$string = "Well that's \"different.\"";

echo "filter_var: ".filter_var($string, FILTER_SANITIZE_STRING)."\n";
echo "htmlentities: ".htmlentities($string, ENT_QUOTES)."\n";
echo "htmlspecialchars: ".htmlspecialchars($string, ENT_QUOTES)."\n";

输出:

filter_var: Well that&#39;s &#34;different.&#34; 
htmlentities: Well that&#039;s &quot;different.&quot; 
htmlspecialchars: Well that&#039;s &quot;different.&quot;

标签: phpencodinghtml-entitiessanitizationfilter-var

解决方案


这是因为filter扩展与 HTML 处理无关。它不使用 HTML 实体转换表。它只是基于 ASCII 值的愚蠢编码。

  • "在 ASCII 中是 34
  • '在 ASCII 中是 39

这同样适用于filter扩展转换为 HTML 编码形式的任何其他字符。它采用十进制的 ASCII 数值,前置&#和附加;。而已!它既简单又高效,即使它不是很正确。

没有冒犯任何人,但是将这个扩展用于任何与 HTML 相关的东西是一个相当愚蠢的想法。现在不推荐使用该常量FILTER_SANITIZE_STRING,并将在未来的 PHP 版本中将其删除。存在一个过滤器FILTER_SANITIZE_FULL_SPECIAL_CHARS,它只是一个包装器htmlspecialchars(),但我想不出任何理由在简单htmlspecialchars()函数上使用它。

其中一些过滤器是惰性 PHP 时代的遗留物。开发人员使用了诸如魔术引号之类的惰性安全方法,这些方法没有提供足够的安全性,并且经常导致更多的混乱。这些 HTML 过滤器在创建时考虑了相同的惰性方法。提供一些东西来缓解 XSS 总比没有好。但是,这绝对不再是推荐的做法。请使用适当的函数正确格式化输出以避免 XSS,而不是依赖过滤器进行清理。


推荐阅读