最近在工作中发现了一个有趣的问题,因为之前在使用 htmlspecialchars 函数对 单、双引号 等容易造成SQL注入的敏感字符进行处理时,都是直接将要处理的数据作为参数传入该函数即了事。因为之前从网络中众多blog以及各类在线手册(如 W3CSchool)中查询 htmlspecialchars 的特点时,大都会得到这么一个“结论”:htmlspecialchars 函数把一些预定义的字符转换为HTML实体,预定义的字符是:
& (和号) 成为 &
" (双引号) 成为 "
' (单引号) 成为 '
< (小于) 成为 <
> (大于) 成为 >
然而在实际应用过程中,发现事实并非完全如此:如果仅向 htmlspecialchars 函数中传入第一个参数,也就是可能包含符合“预定义字符”的待处理字符串,则 htmlspecialchars 仅会处理 &、"、< 和 > ,而唯独不会处理 ' 单引号,感兴趣的朋友可以试验一下。
查阅PHP手册后,发现上面赫然写着:
The translations performed are:
'&' (ampersand) becomes '&'
'"' (double quote) becomes '"' when ENT_NOQUOTES
is not set.
"'" (single quote) becomes ''' only when ENT_QUOTES
is set.
'<' (less than) becomes '<'
'>' (greater than) becomes '>'
也就是说,只有在调用 htmlspecialchars 函数时,主动传递了第二个参数,且是 ENT_QUOTES
时(第二个参数如没有传递,则默认是
ENT_COMPAT:Will convert double-quotes and leave single-quotes alone.
),单引号才会被转义为HTML字符实体。
顺便说一下,由于对PHP手册中参数含义的理解有误:ENT_QUOTES:Will convert both double and single quotes.
(
我对这个解释的理解是:当传入的第二个参数是
ENT_QUOTES
时,仅会转义双引号和单引号为HTML字符实体,而不会转义剩下的预定义字符 &、< 和 > )。
其实,只需要传递第二个参数 ENT_QUOTES ,以 htmlspecialchars($str, ENT_QUOTES); 形式调用,即可转义全部预定义字符串。