PHP字符串——编码与转义
因为PHP程序经常与HTML页、Web地址(URL)以及数据库交互,所以PHP提供⼀些函数来帮助你处理这些类型的数据。HTML、Web页地址和数据库命令都是字符串,但是它们每个都要求不同的字符以不同的⽅法来转义。例如,在Web地址中⼀个空格被写成%20,⽽直接量⼩于符号(<)在HTML⽂档中必须写作<。PHP有许多内置函数来转换和取得这些编码。
HTML:在HTML中特殊的字符以实体(entity)表⽰,如&;和<。这⾥有两个PHP函数来把字符串中的特殊字符转换为实体,⼀个⽤于删除HTML标签,⼀个仅⽤于提取meta标签。
对所有特殊字符进⾏实体引⽤:函数htmlentities()将HTML字符转换为对应的实体(除了空格符)。包括⼩于符号(<)、⼤于符号(>)、与号(&)和重⾳字符。(entity实体)
只对HTML语法字符进⾏实体引⽤:函数htmlspacialchars()转换最⼩的实体集来⽣成合法的HTML。下⾯的实体被转换:
与符号(&)被转换成&
双引号(")被转换成"
单引号(')被转换成'(就像调⽤htmlentities()时使⽤ENT_QUOTES的效果)
⼩于号(<)被转换成<
⼤于号(>)被转换成>
如果有⼀个应⽤程序来显⽰⽤户填⼊表单的数据,则要在显⽰和保存数据之前通过htmlspecialchars()处理数据。如果没有处理的话,⼀旦⽤户提交了像"angle<30"或"sturm & drang"这样的字符串,浏览器会⼈为这些特殊的字符是HTML,从⽽得到⼀个混乱的页⾯。
删除HTML标签
函数strip_tags()从字符串中删除HTML标签:
$input='<p>Howdy,"Cowboy"</p>;
$output=strip_tags($input);//$output是'Howdy,"Cowboy"'
函数可以有第⼆个参数来指定在字符串中留下的标签。之列出标签的开始形式,在第⼆个参数中列出的标签结束形式也将被保留:$input='The <b>bold</b> tags will<i>stay</i><p>';
$output=strip_tags($input,'<b>');//$output是'The <b>bold</b> tags will stay'
在保留标签中的属性不会被strip_tags()改变。由于HTML标签属性(例如style和onmouseover)可以影响Web页⾯的外观和⾏为,所以⽤strip_tags()保留⼀些标签可能会导致⽆法删除所有潜在的冗余内容。
提取元标签
如果你把Web页⾯的HTML存在⼀个字符串中,函数get_meta_tags()可返回包含该页⾯中元标签(meta tag)内容的数组。元标签的名字(keywords、author、escription等)成为数组的键,⽽元标签的内容则成为对应的值:
$meta_tags=get_meta_tags('ample/');
echo "Web page made by {$meta_tags[author]}";
函数⼀般的形式是:
$array=get_meta_tags(filename[,use_include_path]);
可以指定参数use_include_path为true,这样可使PHP尝试⽤标准包含路径打开⽂件。
URL:PHP提供了⼀些函数⽤于对URL进⾏编码和解码。有两种⽅法对URL编码,其区别在于如何处
理空格。第⼀种(根据RFC1738规范)把空格当做URL中的另⼀个⾮法字符并把它编码为%20。第⼆种(执⾏application/x-www-form-urlencoded系统)把空格编码为⼀个+并且把它⽤于建⽴查询的字符串中。
注意并不需要对⼀个完整的URL使⽤这些函数,例如ample/hello,因为它们会转义冒号和反斜杠:
http%3A%ample%2Fhello
应该只编码部分URL(在ample/后⾯的部分),随后再加上协议和域名。
RFC1738编码和解码
要把字符串依照URL约定编码,可以使⽤rawurlencode():
$output=rawurlencode(input);
该函数接收⼀个字符串并返回对该字符串的拷贝,该拷贝中把⾮法URL字符按%dd约定编码。
如果你要为⼀个页⾯⾥的链接动态⽣成超级链接地址,则需要⽤rawurlencode()转换它们:
$name="Programming PHP";
$output=rawurlencode($name);
echo "localhost/$output";
localhost/Programming%20PHP
函数rawurldecode()⽤于解码被编码过的URL字符串:
$encoded='Programming%20PHP';
echo rawurldecode($encoded);
Programming PHP
查询字符串编码
urlencode()和urldecode()函数和它们原始版本(即rawurlencode()和rawurldecode())的不同仅在于它们把空格编码为加号(+),⽽不是%20。这是⽤于创建查询字符串(query string)和cookie值的格式,但是因为这些值在通过表单或cookie传送时会⾃动解码,所以你不需要使⽤这些函数来处理当前页的查询字
符串或cookie。这两个函数对于⽣成查询字符串是很有⽤的:
$base_url='le/q=';
$query='PHP sessions -cookies';
$url=$base_url.urlencode($query);
echo $url;
le/q=PHP+sessions+cookies
SQL:绝⼤多数数据库系统都要求将SQL查询字符串进⾏转义。SQL的转义⽅法相当简单——在单引号、双引号、空字节和反斜杠前⾯加上⼀个反斜杠(\)。addslashes()函数可添加这些反斜杠,stripslashes()函数则删除它们:
$string=<<<The_end
"It's never going to work," she cried,
as she hit the backslash(\)key.
The_End;
echo addslashes($string);
\"It\'s never going to work,\"she cried,
as she hit the backslash (\\) key.
echo stripslashes($string);
"It's never going to work," she cried,
as she hit the backslash (\) key.
提⽰:⼀些数据库(如SYBASE)⽤另⼀个单引号为单引号转义,⽽不是⼀个反斜杠。对于这些数据库,可以在php.ini⽂件中打开
magic_quotes_sybase。
数据错误的以代码形式执⾏是漏洞的根本原因,那么修复⽅法当然是让数据只能以数据的形式被SQL层认识并带⼊查询。
如果没有⽤加反斜杠转义,那么id=111'类似的查询条件就会直接带⼊查询语句:select * from table where id='$id'就变成了select * from table where id='111'';查询语句有未闭合的单引号报错
⽽如果我们使⽤了函数addslashes()进⾏反斜杠转义,那么SQL查询语句会变成:select * from table where id='111\'',所以id=111'中的单引号由于被以\'的形式传递,所以会以值的形式执⾏,SQL就会认为id=111'中的单引号是id变量值的⼀部分,那么查询结果有可能存在也有可能不存在,(例如,如果存在id为王⼆⼩'s的数据库值,就存在查询结果),但是最重要的是,单引号在这⾥是以值的形式传递的,这才是最最根本的本质。
1. 对于PHP magic_quotes_gpc=on的情况,
我们可以不对输⼊和输出数据库的字符串数据作,addslashes()和stripslashes()的操作,数据也会正常显⽰。
如果此时你对输⼊的数据作了addslashes()处理,那么在输出的时候就必须使⽤stripslashes()去掉多余的反斜杠。
2. 对于PHP magic_quotes_gpc=off 的情况,必须使⽤addslashes()对输⼊数据进⾏处理,但并不需要使⽤stripslashes()格式化输出。因为addslashes()并未将反斜杠⼀起写⼊数据库,只是帮助mysql完成了sql语句的执⾏。
url编码处理
有的⽹站,外⾯是可以设置标签为“编程's”等这种格式的,但是⼀点击保存,就报错了,特别搞。然后不管哪个访问对应标签的⽂章,都会看到这个报错。这就是由于从⽤户输⼊到PHP代码再到SQL层,其中PHP整合SQL查询语句时的错误编写造成的。
知识的积累过程,总是起先你不懂,⽽后学了⼀点,就颠⼉颠⼉的以为“⼉得矣”,当有⼀天你突然迷茫了,觉得哪⼉似乎没那么形⽽上的通畅,然后你会不⾃主的想到底哪⼉还有问题呢?你会迷茫很久,直到有⼀天终于到了那个缺⾓,然后它是那么美好因为当你到的时候就差不多已经有能⼒填充了。⼀切便豁然开朗。
有的时候,会略显⽆奈,因为⼈们越来越浮躁,⽽安全环境刚建⽴,安全问题刚得到更多的重视,所以⼤多数⼈在“颠⼉颠⼉”的阶段时,已经被业内⼤致认可,所以会特别盲⽬的⾃信,⽽有不少⼈,却是玩了好久,也没想到过还有哪⼉值得迷茫。眼⾼⼿低,永远是⼀个让⼈崩溃的事实。
有的时候,id数据值会被设置为intval($id),这种情况下,如果变量只能是数字,就不会产⽣注⼊了,因为不管输⼊什么都会以数字——及值的形式带⼊数据库查询。然⽽,如果是字符型id值,⽽且还⽤到了addslashes(),是不是就安全了呢?,还真没有,因为如果sql语句形式是select * from table where id="'$_POST[id]'",这种情况,id值被单引号包含,我们要想构造能以代码执⾏的恶意值需要闭合前⾯的单引号,⽽addslashes会将我们输⼊的单引号转移为正常的值形式带⼊查询。这种情况就呵
呵了。好在有的sql语句中参数值没有⽤单引号包含,例如:select * from table where id="$_POST[id]",虽然开启了addslashes转义单引号等特殊字符,但是我们根本就不需要单引号闭合sql查询语句中的id字段,所以照样可以注⼊。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论