发信人: jackyz() 
整理人: dalasthunder(2002-07-25 06:26:48), 站内信件
 | 
 
 
显示格式化的用户输入
 -----------------------------------------------------------------
 作者:ying zhang 译者:limodou
 
   此文档描述了如何根据用户的输入安全地显示格式化输出。我们将讨论显示 未经过滤的输出的危险性,然后提出一个显示格式化输出的安全的方法。下载yi ng20000718.zip[http://phprecord.e-chome.net/docs/ying20000718.zip]并且 把它展开到你的web文档目录下。 
 
 未过滤输出的危险性
 
   如果你只是简单地得到用户的输入,并且原封不动地将它们显示出来,那样 就可能会破坏你的网页。例如,某些别有用心的人可能在他们的注解中嵌入java script脚本,如: 
 
   这是我的注解。<script language="javascript: alert('在这里做一些不好 的事情!')">
   即使用户没有什么不良企图,他们也有可能碰巧输入了一些html代码,破坏 页面的布局。例如,你在一个表格中显示用户的输入,当用户输入中包括了一个 错误嵌套的</table>标记,页面显示就被破坏了。只显示无格式文本
 
   最简单的解决方法应该是只在注解中显示无格式文本。使用htmlspecialcha rs() 函数,可以将所有的特殊字符转换成html特殊字符。例如将变成<b& gt;,转换为html标记的文本表示。这就保证了在注解中没有html标记,从而不会 产生不希望的输出。 
 
   如果你的访客不介意只是输入无格式文本,这个方法就很好,但是如果你能 够提供给他们一些格式化的功能则就更好了。 
 
 使用自定义标记进行格式化
   为了实现格式化输出可以为用户提供自已定义的特殊标记。比如可以允许用 户使用[b]...[/b]来表示黑体设置,[i]...[/i]表示斜体设置。可以对它们进行 简单的字符串替换操作: 
 
 $output = str_replace("[b]", "", $output);
 $output = str_replace("[i]", "", $output);
   做得再好一点,允许用户可以加入链接。例如,用户可以在[link="url"].. .[/link]中输入链接,我们将把它转变成合适的<a href="">...语句。这里 不能只使用简单地字符替换,需要使用正则表达式: 
 $output = ereg_replace('\[link="([[:graph:]]+)"\]', '<a href="\\1">',  $output);
   如果你对ereg_replace()函数不熟悉的话,这句话的意思就是: 
 查找所有[link="..."]出现的地方,将其替换成为<a href="..."> 
   [[:graph:]]表示任意非空字符。请查阅手册中的关于正则表达式的详细内容 。 
   在outputlib.php中的format_output()函数提供了对这些特殊标记的处理, 同时也提供了对其它几个特殊标记的处理。通用的算法是: 
 
 对输出文本调用htmlspecialchars()函数来转换所有的特殊字符为html的特殊字 符 
 对自定义的标记系统地进行字符串替换或正则式替换 
 -------------------------------------------------------------------
 <?php
 function format_output($output) 
 {
 /***********************************************************
 * 处理原始的字符串($output)并且进行格式化处理,使用特殊的与html
 * 相似的标记
 ************************************************************/ 
 
 $output = htmlspecialchars(stripslashes($output));
 /* 新的段落 */ 
 $output = str_replace('[p]', '<p>', $output);
 /* 黑体 */ 
 $output = str_replace('[b]', '', $output);    $output = str_replace ('[/b]', '', $output);
 /* 斜体*/ 
 $output = str_replace('[i]', '', $output);    $output = str_replace ('[/i]', '', $output);
 /* 预览格式 */ 
 $output = str_replace('[pre]', '<pre>', $output);    $output = str_rep lace('[/pre]', '</pre>', $output);
 /* 缩进块 (blockquote) */ 
 $output = str_replace('[indent]', '<blockquote>', $output);    $output  = str_replace('[/indent]',  '</blockquote>', 
 $output);
 /* 锚点*/ 
 $output = ereg_replace(
 '\[anchor="([[:graph:]]+)"\]',  
    '<a name="\\1">', $output);
 /* 链接,注意我们打算阻止Javascript出现在链接中 */ 
 $output = str_replace('[link="javascript',  
     '[link=" javascript', $output);$output = ereg_replace(
 '\[link="([[:graph:]]+)"\]',  
     '<a href="\\1">', $output);$output = str_replace('[/link]',  ' ', $output);      
 return nl2br($output);
 }
 ?>
 -------------------------------------------------------------------
 
 一些注意事项:
 
 记得在调用完tmlspecialchars()之后而不是之前执行字符串替换操作,否则如果 你在后面才调用htmlspecialchars(), 那么在前面你所做的将自定义标记转换为 HTML的特殊标记的工作将付之东流。
 记得在你的替换字符串中查找HTML的特殊标记,例如要把"(双引号)看成" ;,因为在前面已经被转换成这样了。可以查阅一下手册中关于htmlspecialchar s()函数的说明。
 nl2br()函数将换行符转换为<br>标记,请再次确认这是在htmlspecialchars()之 后被调用的,而不是前面。
 当转换[links=""]为<a href="">时,你必须保证不让别人在其中插入javascrip t脚本。一个简单的方法就是将 [link="javascript改成[link=" javascript,这 种方法就不会匹配链接模式,并且它将被按原样输出。
 
 outputlib.php
 
   装入test.php脚本来看一下format_output()函数是如何工作的。首先在文本 框中输入下面的文本: 
 
 
 正常的HTML标记不能使用,可以使用特殊标记进行替换:
 
 - 这是 [b]黑体[/b]
 - 这是 [i]斜体[/i]
 - 这是 [link="http://www.phpbuilder.com"]一个链接[/link]
 - 这是 [anchor="test"]一个锚点,和一个 [link="#test"]链接[/link] 到指定 的锚点
 
 [p]这是一个段落分隔
 [pre]这是一个预览格式文本[/pre]
 [indent]这是一个缩进文本[/indent]
 示范结束。
 
   到目前只有少量的标记可以使用--你可以随意增加认为合适的标记。 
 
 
 结论
   这篇文章讨论了显示未经格式化的用户输入的危险性,并且提供了一个通过 自定义标记来显示格式化后的用户输入信息的方法。这个方法可以用在任何想要 接收用户输入的地方,例如: 
 
 留言薄 
 用户注解 
 系统公告 
 等等 
 转自phpbuilder.com
 -----------------------------------------------------------------
 来自:http://phprecord.126.com
 作者:limodou
 
 // limodou出品,必属佳品.呵呵.
  -- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 61.141.204.221]
  | 
 
 
 |