PHP 编码与转义

本文最后更新于:2024年3月18日 凌晨

PHP 编码与转义

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

HTML

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

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

  • 函数htmlentities()将HTML字符转换为对应的实体(除了空格符),包括小于符号<,大于符号>,与符号&和重音字符。
  • 例如:
1
2
3
4
$string = htmlentities("a < b");
echo $string;

a < b
  • 经过实体转义的版本在Web页面中正确地显示了<(如果在页面上点右键,查看源代码可以看到实体<),如你所看到的那样,空格没有被转换成$nbsp;
  • 函数htmlentities()实际上有3个参数:
1
$output = htmlentities(input,quote_style,charset);
  • 如果给了参数,charset则识别字符集,默认的字符集时"ISO-8859-1",参数quote_style控制单引号和双引号是否变成它们实体的形式,ENT_COMPAT(默认值)只转换双引号,ENT_QUOTES两种引号都转换,ENT_NOQUOTES则一种都不转换,没有只转换单引号的选项,例如:
1
2
3
4
5
6
$input = <<<End;
"Stop pulling my hair!" Jane's eyes flashed.<p>
End;
$double = htmlentities($input); // 输出:"Stop pulling my hair!" Jane's eyes flashed.<p>
$both = htmlentities($input,ENT_QUOTES); // 输出:"Stop pulling my hair!" Jane's eyes flashed.<p>
$neither = htmlentities($input,ENT_NOQUOTES); // 输出:"Stop pulling my hair!" Jane's eyes flashed.<p>

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

  • 函数htmlspecialchars()转换最小的实体集来生成合法的HTML,下面的实体被转换:
    • 与符号&被转换成&amp;
    • 双引号"被转换成&quot;
    • 单引号'被转换成&#039;(就像调用htmlentities()时使用ENT_QUOTES的效果)
    • 小于号<被转换成&lt;
    • 大于号>被转换成&gt;
  • 如果有一个应用程序来显示用户填入表单的数据,则要在显示和保存数据之前通过htmlspecialchars()处理数据,如果没有处理的话,一旦用户提交了像angle < 30sturm & drang这样的字符串,浏览器会认为这些特殊的字符时HTML,从而得到一个混乱的页面。
  • htmlentities()类似,htmlspecialchars()可以有3个参数:
1
$output = htmlspecialchars(input,[quote_style,[charset]])
  • 参数quote_stylecharset同它们在htmlentities()中的意义相同。
  • 没有专门的函数来把实体转换回原始的文本,因为很少需要这样做,不过这里有一个相对简单的方法来完成这个任务,使用函数get_html_translation_table()用特定引号的方式获取被任一转换函数使用的转换表,例如,要获得htmlentities()使用的转换表,可以这样做:
1
$table = get_html_translation_table(HTML_ENTITIES);
  • 要在ENT_NOQUOTES模式下获得htmlspecialchars()的转换表,可以这样做:
1
$table = get_html_translation_table(HTML_SPECIALCHARS,ENT_NOQUOTES);
  • 使用转换表的一个小技巧是,用array_flip()翻转它,并把它传给strtr()来得到一个字符串,因此有效的回滚htmlentities()操作的方法是:
1
2
3
4
5
6
$str = htmlentities("a < b");// 现在被编码了。
$table = get_html_translation_table(HTML_ENTITIES);
$rev_trans = array_flip($table);
echo strtr($str,$rev_trans);// 恢复到正常。

a < b
  • 当然,你也可以取出转换表,增加你想要它转化的其他东西,然后使用strtr(),例如,如果想让htmlentities()把空格编码为&nbsp;,可以这样做:
1
2
3
$table = get_html_translation_table(HTML_ENTITIES);
$table[' '] = ' ';
$encoded = strtr($original,$table);

删除HTML标签

  • 函数strip_tags()从字符串中删除HTML标签:
1
2
$input = '<p>Howdy, "Cowboy"</p>';
$output = strip_tags($input); //$output是'Howdy, "Cowboy"'
  • 函数可以有第二个参数来指定在字符串中留下的标签,只列出标签的开始形式,在第二个参数中列出的标签结束形式也将被保留:
1
2
$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等)成为数组的键,而元标签的内容则成为对应的值:
1
2
3
4
$meta_tags = get_meta_tags('http://www.example.com/');
echo "Web page made by {$meta_tags[author]}";

Web page made by John Doe
  • 函数的一般形式是:
1
$array = get_meta_tags(filename[,use_include_path]);
  • 可以指定参数use_include_path为true,这样可使PHP尝试用标准包含路径打开文件。

URLs URL

  • PHP提供了一些函数用于对URL进行编码和解码,实际上有两种方法对URL编码,其区别在于如何处理空格,第一种(根据RFC1738规范)把空格当作URL中的另一个非法字符并把它编码为%20,第二种(执行application/x-www-form-urlencoded系统)把空格编码为一个+并且把它用于建立查询的字符串中。
  • 注意并不需要对一个完整的URL使用这些函数,例如http://www.example.com/hello,因为它们会转义冒号和反斜杠:
1
http%3A%2F%2Fwww.example.com%2Fhello

RFC1738编码和解码

  • 要把字符串依照URL约定编码,可以使用rawurlencode();
1
$output = rawurlencode(input);
  • 该函数接受一个字符串并返回对该字符串的拷贝,该拷贝中把非法URL字符按%dd约定编码。
  • 如果你要为一个页面里的链接动态生成超级链接地址,则需要用rawurlencode()转换它们:
1
2
3
4
5
$name = "programming PHP";
$output = rawurlencode($name);
echo "http://localhost/$output";

http://localhost/Programming%20PHP
  • 查询字符串编码。
  • urlencode()urlencode()函数和它们原始版本(即rawurlencode()rawurldecode())的不同仅在于它们把空格编码为加号+,而不是%20,这是用于创建查询字符串(query string)和cookie值得格式,但是因为这些值在通过表单或cookie传送时会自动解码,所以你不需要使用这些函数来处理当前页的查询字符串或cookie,这两个函数对于生成查询字符串是很有用的:
1
2
3
4
5
6
$base_url = 'http://google.com/q=';
$query = 'PHP sessions -cookies';
$url = $base_url.urlencode($query);
echo $url;

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

SQL

  • 绝大多数数据库系统都要求将SQL查询字符串进行转义,SQL的转义方法相当简单–在单引号,双引号,空字节和反斜杠前面加上一个反斜杠(\),addslashes()函数可添加这些反斜杠,stripslashes()函数则删除它们:
1
2
3
4
5
6
7
8
9
10
11
12
13
$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_quores_sybase

C语言字符串编码

  • addcslashes()函数模仿C编程语言的处理方式,通过在字符前加反斜杠来转义任意字符,除了下表中的字符,ASCII值小于32或大于126的字符将使用它们的八进制值(例如,“\002”)进行编码,addcslashes()stripcslapshes()函数常常被用于非标准的数据库系统,这些系统对哪些字符需要被转义有自己的要求。
ASK值 编码
7 \a
8 \b
9 \t
10 \n
11 \t
12 \f
13 \r
  • 调用addcslashes()时有两个参数–string是要编码的字符串,charset是要转义的字符:
1
$escaped = addcslashes(string,charset);
  • ..结构来指定要转义字符的范围:
1
2
3
echo addcslashes("hello\tworld\n","\x00..\x2fz..\xff");

hello\\tworld\\n
  • 如果将0,a,b,f,n,r,tv指定在要转换的字符范围中,要特别注意它们会被转换成\0,\a等,C和PHP可以识别这些转义序列(如\0在PHP中时预定义序列,表示NULL),可能会引起混乱。
  • stripcslashes()接受一个字符串并返回去掉转义后的新字符串。
1
$string = stripcslapshes(escaped);
  • 例如:
1
$string = stripcslapshes('hello\tworld\n');	// 此时字符串内容为"helloworld"

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!