首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

4.5  编码和转义

Encoding and Escaping

因为PHP程序经常与HTML页、web地址(URL)以及数据库交互,所以PHP提供一些函数来帮助你处理这些类型的数据。HTML、web页地址和数据库命令都是字符串,但是它们每个都要求不同的字符以不同的方法来转义。例如,在web地址中一个空格被写作%20,而直接量小于符号(<)在HTML文档中必须写作&lt。PHP有许多内置函数来转换和取得这些编码。

4.5.1  HTML

HTML

在HTML中特殊的字符以实体(entity)表示,如 &amp; 和 &lt;。这里有两个PHP函数来把字符串中的特殊字符转换为实体,一个用于删除HTML标签,一个仅用于提取meta标签。

4.5.1.1  对所有特殊字符进行实体引用

函数htmlentities( )将HTML字符转换为对应的实体(除了空格符)。包括小于符号(<)、大于符号(>)、与号(&)和重音字符。

例如:

$string = htmlentities("Einstürzende Neubauten");

echo $string;

Einstürzende Neubauten

经过实体转义的版本在web页面中正确地显示了ü(如果在页面上点右键,查看源代码可以看到实体&uuml;)。如你所看到的那样,空格没有被转换成&nbsp;

函数htmlentities( )实际上有3个参数:

$output = htmlentities(input, quote_style, charset);

如果给了参数,charset则识别字符集。默认的字符集是“ISO-8859-1”。参数quote_style 控制单引号和双引号是否变成它们实体的形式。ENT_COMPAT(默认值)只转换双引号;ENT_QUOTES两种引号都转换;ENT_NOQUOTES则一种都不转换。没有只转换单引号的选项,例如:

$input = <<< End

"Stop pulling my hair!"  Jane's eyes flashed.<p>

End;

$double = htmlentities($input);

// &quot;Stop pulling my hair!&quot;  Jane's eyes flashed.&lt;p&gt;

$both = htmlentities($input, ENT_QUOTES);

// &quot;Stop pulling my hair!&quot;  Jane&#039;s eyes flashed.&lt;p&gt;

$neither = htmlentities($input, ENT_NOQUOTES);

// "Stop pulling my hair!"  Jane's eyes flashed.&lt;p&gt;

4.5.1.2  只对HTML语法字符进行实体引用

函数htmlspecialchars(  )转换最小的实体集来生成合法的HTML。下面的实体被转换:

l          与符号 (&)被转换成 &amp;

l          双引号(")被转换成 &quot;

l          单引号 (') 被转换成 &#039; (就像调用htmlentities( )时使用ENT_QUOTES 的效果)

l          小于号 (<)被转换成 &lt;

l          大于号 (>)被转换成 &gt;

如果有一个应用程序来显示用户填入表单的数据,则要在显示和保存数据之前通过htmlspecialchars( )处理数据。如果没有处理的话,一旦用户提交了像“angle < 30sturm & drang”这样的字符串,浏览器会认为这些特殊的字符是HTML,从而得到一个混乱的页面。

和htmlentities( )类似,htmlspecialchars( )可以有3个参数:

$output = htmlspecialchars(input, [quote_style,[charse]]);

参数quote_style 和 charset 同它们在htmlentities( )中的意义相同。

没有专门的函数来把实体转换回原始的文本,因为很少需要这样做。不过这里有一个相对简单的方法来完成这个任务。使用函数get_html_translation_table( )用特定引号的方式获取被任一转换函数使用的转换表。例如,要获得htmlentities( )使用的转换表,可以这样做:

$table = get_html_translation_table(HTML_ENTITIES);

要在ENT_NOQUOTES模式下获得htmlspecialchars( )的转换表,可以这样做:

$table = get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES);

使用转换表的一个小技巧是,用array_flip( )翻转它、并把它传给strtr( )来得到一个字符串。因此有效的回滚htmlentities( )操作的方法是:

$str = htmlentities("Einstürzende Neubauten");  //现在被编码了

$table = get_html_translation_table(HTML_ENTITIES);

$rev_trans = array_flip($table);

echo strtr($str,$rev_trans);  // 回复到正常

Einst Ürzende Neubauten

当然,你也可以取出转换表,增加你想要它转换的其他东西,然后使用strtr( )。例如,如果想让htmlentities( )把空格编码为&nbsp;s,可以这样做:

$table = get_html_translation_table(HTML_ENTITIES);

$table[' '] = '&nbsp;';

$encoded = strtr($original, $table);

4.5.1.3  删除HTML标签

函数strip_tags( )从字符串中删除HTML标签:

$input  = '<p>Howdy, &quot;Cowboy&quot;</p>';

$output = strip_tags($input);

// $output is 'Howdy, &quot;Cowboy&quot;'

函数可以有第二个参数来指定在字符串中留下的标签。只列出标签的开始形式,在第二个参数中列出的标签结束形式也将被保留:

$input  = 'The <b>bold</b> tags will <i>stay</i><p>';

$output = strip_tags($input, '<b>');

// $output is 'The <b>bold</b> tags will stay'

在保留标签中的属性不会被strip_tags( )改变。由于HTML标签属性(例如styleonmouseover)可以影响web页面的外观和行为,所以用strip_tags( )保留一些标签可能会导致无法删除所有潜在的冗余内容。

4.5.1.4  提取元标签

如果你把web页面的HTML存在一个字符串中,函数get_meta_tags( )可返回包含该页面中元标签(meta tag)内容的数组。元标签的名字(keywords、author、escription等)成为数组的键,而元标签的内容则成为对应的值:

$meta_tags = get_meta_tags('http://www.example.com/');

echo "Web page made by {$meta_tags[author]}";

Web page made by John Doe

函数的一般形式是:

$array = get_meta_tags(filename [, use_include_path]);

可以指定参数use_include_path 为true,这样可使PHP尝试用标准包含路径打开文件。

4.5.2  URLs URL

PHP提供了一些函数用于对URL进行编码和解码。实际上有两种方法对URL编码,其区别在于如何处理空格。第一种(根据RFC 1738规范)把空格当作URL中的另一个非法字符并把它编码为%20。第二种(执行application/x-www-form-urlencoded 系统)把空格编码为一个+并且把它用于建立查询的字符串中。

注意并不需要对一个完整的URL使用这些函数,例如http://www.example.com/hello,因为它们会转义冒号和反斜杠:

http%3A%2F%2Fwww.example.com%2Fhello

应该只编码部分URL(在http://www.example.com/后面的部分),随后再加上协议和域名。

4.5.2.1  RFC 1738编码和解码

要把字符串依照URL约定编码,可以使用rawurlencode( )

$output = rawurlencode(input);

该函数接收一个字符串并返回对该字符串的拷贝,该拷贝中把非法URL字符按%dd约定编码。

如果你要为一个页面里的链接动态生成超级链接地址,则需要用rawurlencode( )转换它们

$name = "Programming PHP";

$output = rawurlencode($name);

echo "http://localhost/$output";

http://localhost/Programming%20PHP

函数rawurldecode( )用于解码被编码过的URL字符串:

$encoded = 'Programming%20PHP';

echo rawurldecode($encoded);

Programming PHP

4.5.2.2  查询字符串编码

urlencode( )和urldecode( )函数和它们原始版本(即rawurlencode()和rawurldecode())的不同仅在于它们把空格编码为加号(+),而不是%20。这是用于创建查询字符串(query string)和cookie值的格式,但是因为这些值在通过表单或cookie传送时会自动解码,所以你不需要使用这些函数来处理当前页的查询字符串或cookie。这两个函数对于生成查询字符串是很有用的:

$base_url = 'http://www.google.com/q=';

$query = 'PHP sessions -cookies';

$url = $base_url . urlencode($query);

echo $url;

http://www.google.com/q=PHP+sessions+-cookies

4.5.3  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

4.5.4  C语言字符串编码

C-String Encoding 

addcslashes( )函数模仿C编程语言的处理方式,通过在字符前加反斜杠来转义任意字符。除了在表4-4中的字符,ASCII值小于32或大于126的字符将使用它们的八进制值(例如,"\002")进行编码。addcslashes( )stripcslashes( )函数常常被用于非标准的数据库系统,这些系统对哪些字符需要被转义有自己的要求。

表4-4:可以被addcslashes( ) 和stripcslashes( )识别的单字符转义

ASK值

编  码

7

\a

8

\b

9

\t

10

\n

11

\t

12

\f

13

\r

调用addcslashes( )有两个参数——string是要编码的字符串,charset是要转义的字符:

$escaped = addcslashes(string, charset);

".."结构来指定要转义字符的范围:

echo addcslashes("hello\tworld\n", "\x00..\x1fz..\xff");

hello\\tworld\\n

如果将'0', 'a', 'b', 'f', 'n', 'r', 't','v'指定在要转换的字符范围中,要特别注意它们会被转换成'\0', '\a'等。C和PHP可以识别这些转义序列(如\0在PHP中是预定义序列,表示NULL),可能会引起混乱。

stripcslashes( )接受一个字符串并返回去掉转义后的新字符串。

$string = stripcslashes(escaped);

例如:

$string = stripcslashes('hello\tworld\n');

//此时字符串内容为“hello\tworld\n”

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论