精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● PHP>>实用技巧>>[转载]显示格式化的用户输入

主题:[转载]显示格式化的用户输入
发信人: 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特殊字符。例如将变成&lt;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=&quot;([[:graph:]]+)&quot;\]',  
   '<a name="\\1">', $output);
/* 链接,注意我们打算阻止Javascript出现在链接中 */ 
$output = str_replace('[link=&quot;javascript',  
    '[link=&quot; javascript', $output);$output = ereg_replace(
'\[link=&quot;([[:graph:]]+)&quot;\]',  
    '<a href="\\1">', $output);$output = str_replace('[/link]',  '
', $output);      
return nl2br($output);
}
?>
-------------------------------------------------------------------

一些注意事项:

记得在调用完tmlspecialchars()之后而不是之前执行字符串替换操作,否则如果
你在后面才调用htmlspecialchars(), 那么在前面你所做的将自定义标记转换为
HTML的特殊标记的工作将付之东流。
记得在你的替换字符串中查找HTML的特殊标记,例如要把"(双引号)看成&quot
;,因为在前面已经被转换成这样了。可以查阅一下手册中关于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]

[关闭][返回]