php, html, javascript, mysql 之间的特殊字符处理
特殊字符指在程序中有具有特殊的控制意义的字符,一般来讲各个程序语言所使用
的特殊字符大部分都来源于传统的 C 语言,加上自身的扩展,便较为完整的满足了编程
需求。
程序自身的转义处理能够解决自身的处理需求,问题基本上都集中在程序语言之间
的不同转移策略所带来的匹配差异上。几乎对所有语言来说单引号(')和双引号(")
都会带来一些麻烦。
php 中对字符的转义采用反斜杠(\),再与数据库进行交互时采用的函数有:
1 addslashes($str);
这个函数是重新生成一个转义后的字符串,使用时要注意。
如 $str = '""""""""';//这个解析没有问题,但是输出时就会出现问题;
1 htmlspecialchars($str);
这个是在输出时处理对 html 具有特殊意义的字符;
1 striptslashes($str);
这个是在输出时去掉转义用的反斜杠(\)
Javascript 中则使用反斜杠(\)对特殊字符转义;
查询特殊字符无法使用(#, ?, =, &)的原因是因为该类特殊字符属于 html 语言 url
参数传递(Get 方式)时用来进行参数拼接的,直接使用会导致参数传递紊乱,结局方法是:
前台字符串参数传递使用 javascript 的 urlencode 内置函数进行包裹,将字符串参数中的
特殊字符转为相应的 unicode 编码,php 取参时无需进行处理,能够直接显示该 unicode
所代表的特殊字符。
Php 与 Mysql 中需要特别注意对于反斜杠(\)的转义处理。反斜杠是比较通用的转义
符号,要匹配字符串中的反斜杠字符('\'),原则上来说只需要使用 2 个反斜杠(\\)
就可以了,但是 php 与 mysql 中在进行反斜杠匹配时却需要 3 或 4 个反斜杠(\\\\)
来匹配 1 个字符串中的反斜杠(\)。如为了将字符串中的 1 个反斜杠替换为 4 个反斜
杠(\\\\)以使 sql 语句能够匹配数据库中的具有 1 个反斜杠(\) 的字段的记录,需要
使用以下的转换:
1 $str = preg_replace("/\\\\/", "\\\\\\\\\\\\\\\\", $str);
2 $str = preg_replace("/'/", "''", $str);
3 $str = preg_replace("/_/", "'_", $str);
4 $str = preg_replace("/%/", "'%", $str);
这样数据库中的匹配才是合理的。使用之后,为了将 $str 回显,要做相应的逆向处理:
1 $str = preg_replace("/\\\\\\\\\\\\\\\\/", "\\\\", $str);
2 $str = preg_replace("/''/", "'", $str);
3 $str = preg_replace("/'_/", "_", $str);
4 $str = preg_replace("/'%/", "%", $str);
5 $str = htmlspecialchars($str);
这样便满足了特殊字符的查询处理需求。
sql 中的特殊字符有下划线(_), 百分号(%),和单引号(');
1) php (\) 转义符问题
sql 中有特殊含义:表示换行
需要转为 \\\ (3个) 进行匹配;
写成三个'\'的原因是反斜线符号会被语法分析程序剥离一次,在进行模式匹配时,
又会被剥离一次,最后会剩下一个反斜线符号接受匹配
如:
数据库中有数据如下:
1 "*_.%'"a@k
2 "*_.%'"a@k\'
3 "*_.%'"a@k\\
4 "*_.%'"a@k\\\
5 "*_.%'"a@k\\\\
1 搜索 "*_.%'"a@k 会匹配 "*_.%'"a@k;
2 搜索 "*_.\%'"a@k 会匹配 "*_.%'"a@k;
1 搜索 "*_.%'"a@k\ sql 会报语法错误
2 搜索 "*_.\%'"a@k\ sql 会报语法错误
1 搜索 "*_.%'"a@k\\ 匹配 0 行
2 搜索 "*_.\%'"a@k\\ 匹配 0 行
1 搜索 "*_.%'"a@k\\\% 匹配结果如下:
2 "*_.%'"a@k\'
3 "*_.%'"a@k\\
4 "*_.%'"a@k\\\
5 "*_.%'"a@k\\\\
1 搜索 "*_.%'"a@k\\\\% 匹配结果如下:
2 "*_.%'"a@k\'
3 "*_.%'"a@k\\
4 "*_.%'"a@k\\\
5 "*_.%'"a@k\\\\
1 搜索 "*_.\%'"a@k\\\\\ 匹配 0 行
2 搜索 "*_.\%'"a@k\\\\\\ 匹配 0 行
3 搜索 "*_.\%'"a@k\\\\\\\ 匹配 1 行
4 搜索 "*_.\%'"a@k\\\\\\\\ 匹配 1 行
总结:
反斜杠做查询时要变 1 个为 4 个,这样总能得到正确的结果。
另:
1 $senameEnter = preg_replace("/\\\/", "\\\\\\\\\\\\\\\\", $senameEnter);
这句代码将 $senameEnter 中的一个反斜杠(\)替换为四个反斜杠(\\\\),以匹配
sql 中查询一个反斜杠(\)需要用四个反斜杠(\\\\)去匹配。
为了统一替换的数值可以设为使用四个反斜杠(\\\\)替换一个,如下面代码:
1 $senameEnter = preg_replace("/\\\\/", "\\\\\\\\\\\\\\\\", $senameEnter);
php 正则表达式中反斜杠(\)是用来进行特殊字符转义的,匹配反斜杠原则上只要
使用两个反斜杠(\\),但是实际使用时却需要三个反斜杠(\\\)进行匹配。php 字符
串中需要由四个反斜杠(\\\\)来表示一个反斜杠的替代。详细的原因比较复杂,需要
根据程序设计的内部机制进行解释。
2) & 符号问题
& 符号的问题原因是:在url传递参数时这个符号代表了传递字符的连接符。
同样存在问题的还有等号(=)和问号(?)。
解决方法:
js 拼凑URL时先对这三个符号进行处理,传递之后再进行逆向处理。
如果编码是将其编码为相应的unicode码,后台无需在特别处理。
1 url = url.replace(/\?/g,"%3F").replace(/&/g,"%26").replace(/=/g,"%3D");
使用 jquery 取出来的字符串如果包含 '&' 符号,javascript 会将其妆化为相应的等式实体 &
回显需要进行特别处理(无内置函数):
1 sename = $(obj).html().replace(/&/g, '&');