发布文章帖子等一般都是会页面html做过滤、转ubb码等,但是在多层复杂嵌套的时候会遇到很多问题,如果你不想用户使用html完全可以使用strip_tags过滤,如果需要使用html会用一些手段如正则匹配很复杂或者使用一些框架这些做法很消耗资源,有什么办法有效的限制用户的html代码,这里介绍一个php的扩展 tidy这个扩展专门做html处理,我这里写了个简单的html自定义过滤,你可以对一些复杂的html数据进行有效的数据。功能只有过滤有兴趣的朋友也可以扩展。
/**
* HTML整理
* 自定义HTML允许使用的标签和属性
* 变量$allow_tag说明
* 键为标签名 值是允许使用的属性 *代表全部运行 如果不允许使用属性配置NULL或者空
* 需要支持更多html标签$allow_tag设置
* 需要统一支持某个属性$allow_public_attribute配置
* 此功能需要服务器支持tidy模块
* tidyHtml::filter($html) 成功返回处理后的数据 如果不支持或者失败返回原数据
*
* @author weishanli
*/
class tidyHtml {
/**
* 需要处理的HTML
*
* @var array
*/
static public $tree_html = '';
/**
* 单标签HTML
*
* @var array
*/
static public $single_tag = array('img');
/**
* 公共允许使用的的属性
* @var array
*/
static public $allow_public_attribute = array(
'align'
);
/**
* 允许使用的标签
*
* @var array
*/
static public $allow_tag = array(
'a' => array('href'),
'b' => '',
'i' => '',
'u' => '',
'p' => '',
'ol' => '',
'li' => '',
'ul' => '',
'br' => '',
'img' => array('src'),
'div' => array('align'),
'font' => array('size', 'color'),
'span' => array('style')
);
/**
* 过滤HTML
*
* @param string $html html
* @return string
*/
static public function filter($html) {
// 服务器需要支持tidy
if ( ! function_exists('tidy_parse_string')) {
return $html;
} else {
$tree_html = tidy_parse_string($html, array(), 'UTF8');
self::$tree_html = $tree_html->body()->child;
}
self::$tree_html = self::tidy(self::$tree_html);
return self::$tree_html;
}
static public function tidy($data) {
$new_data = '';
if ($data) {
foreach($data as $r) {
if ($r->name) { // 标签名
if (isset(self::$allow_tag[$r->name])) { // 是否允许使用的标签
$new_data .= 'name;
if ($r->attribute && self::$allow_tag[$r->name] != 'none') {
foreach ($r->attribute as $key => $value) { // 属性
if (self::$allow_tag[$r->name] == '*') {
$new_data .= ' '.$key.'="'.$value.'"';
} elseif ((is_array(self::$allow_tag[$r->name]) && in_array($key, self::$allow_tag[$r->name]))
|| in_array($key, self::$allow_public_attribute)) { // 允许使用的属性
$new_data .= ' '.$key.'="'.$value.'"';
}
}
}
if (in_array($r->name, self::$single_tag)) { // 单标签
$new_data .= ' /';
}
$new_data .= '>';
}
} else { // 标签内的值
$new_data .= trim($r->value);
}
if ($r->child) {
$new_data .= self::tidy($r->child);
}
if ($r->name && isset(self::$allow_tag[$r->name])) {
if (in_array($r->name, self::$single_tag) === FALSE) { // 不是单标签
$new_data .= ''.$r->name.'>';
}
}
}
}
return $new_data;
}
}
$html = file_get_contents('data.php');
echo tidyHtml::filter($html);