php中特殊字符用html代码好还是转义好?
就是在写php时,需要echo特殊字符,比如"这个符号,写入php时是用转义\"好还是用html代码
"
好呢?请教各位,谢谢!
谢谢各位!已经大致明白了,非常感谢各位的耐心解答!
PS.php大神果然不一样,回答都是那么的详细~~在此感谢了!
回复内容:
嗯,因为是纯小白,这个问题可能有点菜,各位大神见谅……
就是在写php时,需要echo特殊字符,比如"这个符号,写入php时是用转义\"好还是用html代码"
好呢?
请教各位,谢谢!
谢谢各位!已经大致明白了,非常感谢各位的耐心解答!
PS.php大神果然不一样,回答都是那么的详细~~在此感谢了!
要明白哪个好的话首先我们就要搞清楚两者之间的区别:
使用转义的话就是相当于输出原字符,既然特殊字符原字符输出了的话就必须和页面的编码方式和浏览器的编码方式有关系。如果页面的编码(如GBK)中不包含该特殊字符的话,或者浏览器的编码方式不包含该特殊字符的话,就会出现乱码。
你所说的HTML代码的正统名字叫做HTML 字符实体,英文名字叫做HTML Entities。使用字符实体的话浏览器会自己将代码转换为正确的字符,就少了对编码方式的要求。关于字符实体的内容你可以多看看这些页面:HTML 字符实体 | HTML Entities
总结来说,使用转义的话方便书写和阅读,但是对页面的编码方式有要求。使用HTML字符实体虽然少了编码方式的显示,但是不便于书写和阅读源码。所以我个人的建议是例如"
这种稍微大众平常一点的字符还是转义输出比较好,而特殊的,可以独立于页面的特殊字符(如 © ® ™ 等)则使用字符实体的形式表现。字符实体这块虽然使用实体号来写会有更大的兼容性,但是个人倾向于用字符实体的名称,原因还是方便阅读。
转义和转义不一样
感性的来看,但凡在字符串本身当中,出现包裹字符串的分隔符(或其他直接使用有特殊意义的字符),都必须转义。但是不同的语言的转义,虽然目的一致,但要转的东西往往完全不同。
“转义\"
好还是用html代码"
好”?前者是PHP字符串的转义,后者是HTML语言的转义。使用场合都不同,所以千万不要混为一谈——完全不是等价讨论的概念。
题主问题中,前者使用的PHP字符串转义,就是双引号包裹的字符串当中,允许转义\"
="
、\n
=LF(0x0A)等字符。后者涉及的HTML转义就是用HTML实体(HTML Entities)表示字符,比如&
=&
。
什么转义都不能省略
PHP的转义不能省略,不用多说(多数时候,不转义明显解析出错啊!)
但这里的问题是:PHP = Hypertext Preprocessor,PHP的输出就是HTML页面。在PHP中写的字符串常量,经常送给浏览器的HTML解析器。题主问的问题也是如此。
所以必须明确:题主的需求很可能涉及二次转义:先写出合法的PHP字符串常量,然后保证浏览器解析HTML后,输出的仍然是字符串的原样,而不会:
- 特殊字符失效
- 破坏HTML DOM结构
- 被注入代码,产生安全问题
PHP和HTML,两个的转义都是不能省略的。题主问题的结论是:前者只做了PHP的转义,这个放在HTML正文中可以,但放在标签的属性值里不行。后者是做了HTML的转义,而PHP无需转义(视同已转义),OK。但重要的是:要知道“为什么”可以,而不是乱试最后“凑巧”可以。
我赞成的做法
虽然第二种可以,但我认为echo '"';
这绝对是一种极其不良的实践。如果评一个“PHP最差编程习惯”,这个绝对有上榜的实力。
因为PHP先构造字符串,再处理成HTML的格式输出,这是一个有先后顺序的需求。如果直接把HTML实体写在PHP的字符串常量里,那就是把两个阶段转义的逻辑混杂在了一起。
在PHP中我比较赞成的方法,是将字符串的内容保持原样,在输出之前用htmlentities
或htmlspecialchars
函数包裹之:(注意这两个函数略有区别,网上资料很多)
header("Content-Type: text/html; charset=utf-8");
echo htmlentities("\"M&M\""); # 显示:"M&M" 查看源代码:"M&M"
这样,写源代码的时候只需关心PHP的逻辑。最后由机器保证前台的输出,和字符串本身一致。
你可能总会在网上见到莫名其妙的真的出现一个“&
”的情况——这就是不单点转义,而是把转义过程自以为是的到处乱放,最终造成重复做两遍HTML转义的错误。
数据可能到处输出,但数据的原样只有一个。不要把数据的原貌混杂到自己都认不清,这也很重要。
如何对付特殊符号?
对付©®™
等特殊符号,以及中文等涉及编码方式的地方,我和 @怡红公子 的看法是不太一致的。我的想法是:
- 出现任何特殊符号,都真的原样写到字符串中去。中文也一样。
- 转义仍然使用htmlentities来做。
- PHP文件尽可能使用UTF-8无BOM格式存储。
- 如果输出的编码不是UTF-8,则在HTML转义的后边,再加一层iconv转换。
因为我认为转义和编码方式还是一个事情的两个阶段,不宜混在一起谈。这个模型就像俄罗斯套娃一样,安装者一定是先装小的再套大的,而拆解者必然是先拆外边再拆里边。以GBK为例的逻辑就是:
- 先有原数据。——
©公司"2014"
- 做成PHP的字符串常量。——
"©公司\"2014\""
以这个样子写进PHP脚本文件中 - 转义HTML实体。——
©公司"2014"
此处PHP知道:字符串中有这些字符,这就行了,内部应该是Unicode存的但是我们可以不关心 - 转成GBK编码。——
©
+B9ABCBBE+"2014"
中间的一段是4个字节的GBK码原始值 - 浏览器解开GBK编码:——
©公司"2014"
- 再解开HTML实体————
©公司"2014"
- 原样输出。
去掉编码,无非就是去掉了步骤4和5,和转义一点关系都不涉及到。
輸出HTML的東西都必須轉義(空格->
)。
永遠不要相信一切輸入。