2008.10.06补充:
有些字符在html里有特别的含义,比如小于号<就表示HTML Tag的开始,这个小于号是不显示在我们最终看到的网页里的。那如果我们希望在网页中显示一个小于号,该怎么办呢?
这就要说到HTML字符实体(HTML Character Entities)了。
一个字符实体(Character Entity)分成三部分:第一部分是一个&符号,英文叫ampersand;第二部分是实体(Entity)名字或者是#加上实体(Entity)编号;第三部分是一个分号。
比如,要显示小于号,就可以写<或者<。
用实体(Entity)名字的好处是比较好理解,一看lt,大概就猜出是less than的意思,但是其劣势在于并不是所有的浏览器都支持最新的Entity名字。而实体(Entity)编号,各种浏览器都能处理。
注意:Entity是区分大小写的。
对于这些特殊字符,使用php的htmlspecialchars可以将它转化为字符实体,而通过htmlspecialchars_decode可以将字符实体转化为我们它代表的字符。比如我们要将某字符串截断,那么这时我们希望的可能是实际的字符;而交给浏览器去显示的时候,我们给的需要是字符实体,以免因为特殊字符造成一些安全或显示方面的问题。
----------------------------------
把总结放到最前面,做一个网页项目,需要考虑以下几点:
1、是否允许用户输入全部字符?
2、数据库中存储原始数据还是转义后的数据?
3、从别处获取数据的时候,知道它是否转义?
也就是说,所有非自己掌控的东西,都要斟酌下,否则造成的可能不仅是页面问题,还有安全问题。
网页上显示的文字,可以分为哪几种呢?我觉得,按照安全、需要的处理方式来分,可以是以下几种:
1、html字符,如;
2、特殊字符,如",如果需要插入数据库的话,就需要进行处理;
3、非法词,反动词汇;
4、普通字母、汉字等。
对于这些字符的存储方式也有两种:
1、如果选择数据库存储原始数据,那么从数据库中取出来的数据就需要htmlspecialchars,去处理html字符;
2、如果选择存储转义后的字符,那么取出直接显示就可以了。
如果选择存储原始数据在数据库中,并且允许用户输入各种字符、文字($enter)。对于用户输入的数据,首先是存入数据库,然后再取出来用于显示。
1、$enter = addslashes($enter);为存入数据库做准备,处理特殊字符。
2、过滤非法词,就是检查是否存在非法词库中的词。
3、写入数据库,这里存储的是原始数据,就是用户输了什么,就是什么。
4、从数据库中取数据$data。
5、对于过长的数据,需要截断,这里需要考虑utf8编码中,汉字占3位,字母1位。
6、转义html字符:$data = htmlspecialchars($data);避免用户输入的文字直接被解释为html代码,造成页面的紊乱和不安全问题。
如果不允许用户输入html字符,则使用strip_tags忽略掉html和php字符,也可以使用正则表达式,去除某些特定的符号等。
如果选择存储转义后的数据放在数据库中,那么截断的时候需要注意,采取以下步骤:
$data = ms_utf8_substr(html_entity_decode($data), 10);
这里,ms_utf8P_substr是我们自己写的一个函数,用来截断utf8的字符,不会产生乱码。如果是原始数据,直接使用即可;如果是转义后的数据,则需要先decode。因为,转义后的数据,会加入一些如反斜杠之类的符号。
function ms_utf8_substr($string,$length) {
$words = 0;
$n = 0;
while ($n < strlen($string) && $words < $length ) {
$t = ord($string[$n]);
if($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
$n++;
$words ++;
} elseif(194 <= $t && $t <= 223) {
$n += 2;
$words += 2;
} elseif(224 <= $t && $t <= 239) {
$n += 3;
$words += 2;
} elseif(240 <= $t && $t <= 247) {
$n += 4;
$words += 2;
} elseif(248 <= $t && $t <= 251) {
$n += 5;
$words += 2;
} elseif($t == 252 || $t == 253) {
$n += 6;
$words += 2;
} else {
$n++;
$words ++;
}
}
$wordscut = substr($string, 0, $n);
return $wordscut;
}
其中,编码的函数:htmlspecialchars和htmlentities基本相同,还可以使用一些参数控制单引号、双引号等的编码方式。解码用:html_entity_decode。