php过滤html标记属性类用法实例


Posted in PHP onSeptember 23, 2014

本文实例讲述了php 过滤html标记属性类及其用法。是PHP项目开发中比较常见的实用技巧。分享给大家供大家参考。具体方法如下:

HtmlAttributeFilter.class.php类文件如下:

<?php 
/** HTML Attribute Filter 
*  Date:  2013-09-22 
*  Author: fdipzone 
*  ver:  1.0 
* 
*  Func: 
*  public strip       过滤属性 
*  public setAllow      设置允许的属性 
*  public setException    设置特例 
*  public setIgnore     设置忽略的标记 
*  private findElements    搜寻需要处理的元素 
*  private findAttributes   搜寻属性 
*  private removeAttributes  移除属性 
*  private isException    判断是否特例 
*  private createAttributes  创建属性 
*  private protect      特殊字符转义 
*/ 
 
class HtmlAttributeFilter{ // class start 
 
  private $_str = '';      // 源字符串 
  private $_allow = array();   // 允许保留的属性 例如:array('id','class','title') 
  private $_exception = array(); // 特例 例如:array('a'=>array('href','class'),'span'=>array('class')) 
  private $_ignore = array();  // 忽略过滤的标记 例如:array('span','img') 
 
 
  /** 处理HTML,过滤不保留的属性 
  * @param String $str 源字符串 
  * @return String 
  */ 
  public function strip($str){ 
    $this->_str = $str; 
 
    if(is_string($this->_str) && strlen($this->_str)>0){ // 判断字符串 
 
      $this->_str = strtolower($this->_str); // 转成小写 
 
      $res = $this->findElements(); 
      if(is_string($res)){ 
        return $res; 
      } 
      $nodes = $this->findAttributes($res); 
      $this->removeAttributes($nodes); 
    } 
    return $this->_str; 
  } 
 
  /** 设置允许的属性 
  * @param Array $param 
  */ 
  public function setAllow($param=array()){ 
    $this->_allow = $param; 
  } 
 
  /** 设置特例 
  * @param Array $param 
  */ 
  public function setException($param=array()){ 
    $this->_exception = $param; 
  } 
 
  /** 设置忽略的标记 
  * @param Array $param 
  */ 
  public function setIgnore($param=array()){ 
    $this->_ignore = $param; 
  } 
 
  /** 搜寻需要处理的元素 */ 
  private function findElements(){ 
    $nodes = array(); 
    preg_match_all("/<([^ !\/\>\n]+)([^>]*)>/i", $this->_str, $elements); 
    foreach($elements[1] as $el_key => $element){ 
      if($elements[2][$el_key]){ 
        $literal = $elements[0][$el_key]; 
        $element_name = $elements[1][$el_key]; 
        $attributes = $elements[2][$el_key]; 
        if(is_array($this->_ignore) && !in_array($element_name, $this->_ignore)){ 
          $nodes[] = array('literal'=>$literal, 'name'=>$element_name, 'attributes'=>$attributes); 
        } 
      } 
    } 
 
    if(!$nodes[0]){ 
      return $this->_str; 
    }else{ 
      return $nodes; 
    } 
  } 
 
  /** 搜寻属性 
  * @param Array $nodes 需要处理的元素 
  */ 
  private function findAttributes($nodes){ 
    foreach($nodes as &$node){ 
      preg_match_all("/([^ =]+)\s*=\s*[\"|']{0,1}([^\"']*)[\"|']{0,1}/i", $node['attributes'], $attributes); 
      if($attributes[1]){ 
        foreach($attributes[1] as $att_key=>$att){ 
          $literal = $attributes[0][$att_key]; 
          $attribute_name = $attributes[1][$att_key]; 
          $value = $attributes[2][$att_key]; 
          $atts[] = array('literal'=>$literal, 'name'=>$attribute_name, 'value'=>$value); 
        } 
      }else{ 
        $node['attributes'] = null; 
      } 
      $node['attributes'] = $atts; 
      unset($atts); 
    } 
    return $nodes; 
  } 
 
  /** 移除属性 
  * @param Array $nodes 需要处理的元素 
  */ 
  private function removeAttributes($nodes){ 
    foreach($nodes as $node){ 
      $node_name = $node['name']; 
      $new_attributes = ''; 
      if(is_array($node['attributes'])){ 
        foreach($node['attributes'] as $attribute){ 
          if((is_array($this->_allow) && in_array($attribute['name'], $this->_allow)) || $this->isException($node_name, $attribute['name'], $this->_exception)){ 
            $new_attributes = $this->createAttributes($new_attributes, $attribute['name'], $attribute['value']); 
          } 
        } 
      } 
      $replacement = ($new_attributes) ? "<$node_name $new_attributes>" : "<$node_name>"; 
      $this->_str = preg_replace('/'.$this->protect($node['literal']).'/', $replacement, $this->_str); 
    } 
  } 
 
  /** 判断是否特例 
  * @param String $element_name  元素名 
  * @param String $attribute_name 属性名 
  * @param Array $exceptions   允许的特例 
  * @return boolean 
  */ 
  private function isException($element_name, $attribute_name, $exceptions){ 
    if(array_key_exists($element_name, $this->_exception)){ 
      if(in_array($attribute_name, $this->_exception[$element_name])){ 
        return true; 
      } 
    } 
    return false; 
  } 
 
  /** 创建属性 
  * @param String $new_attributes 
  * @param String $name 
  * @param String $value 
  * @return String 
  */ 
  private function createAttributes($new_attributes, $name, $value){ 
    if($new_attributes){ 
      $new_attributes .= " "; 
    } 
    $new_attributes .= "$name=\"$value\""; 
    return $new_attributes; 
  } 
 
 
  /** 特殊字符转义 
  * @param String $str 源字符串 
  * @return String 
  */ 
  private function protect($str){ 
    $conversions = array( 
      "^" => "\^",  
      "[" => "\[",  
      "." => "\.",  
      "$" => "\$",  
      "{" => "\{",  
      "*" => "\*",  
      "(" => "\(",  
      "\\" => "\\\\",  
      "/" => "\/",  
      "+" => "\+",  
      ")" => "\)",  
      "|" => "\|",  
      "?" => "\?",  
      "<" => "\<",  
      ">" => "\>"  
    ); 
    return strtr($str, $conversions); 
  } 
 
} // class end 
 
?>

demo示例代码如下:

<?php 
require('HtmlAttributeFilter.class.php'); 
 
$str = '<div class="bd clearfix" id="index_hilite_ul"><ul class="list"><li><img src="http://su.bdimg.com/static/skin/img/logo_white.png" width="118" height="148"><div class="cover"><a class="text" href="https://3water.com"><strong>yuna</strong><p>love</p></a><strong class="t g">want to know</strong><a href="/login.html" class="ppBtn"><strong class="text">YES</strong></a></div></li></ul></div>'; 
 
$obj = new HtmlAttributeFilter(); 
 
// 允许id属性 
$obj->setAllow(array('id')); 
 
$obj->setException(array( 
  'a' => array('href'),  // a 标签允许有 href属性特例 
  'ul' => array('class') // ul 标签允许有 class属性特例 
)); 
 
// img 标签忽略,不过滤任何属性 
$obj->setIgnore(array('img')); 
 
echo 'source str:<br>'; 
echo htmlspecialchars($str).'<br><br>'; 
echo 'filter str:<br>'; 
echo htmlspecialchars($obj->strip($str)); 
?>

本文完整源码点击此处本机下载。

希望本文所述对大家的PHP程序设计有所帮助。

PHP 相关文章推荐
PHP 字符串操作入门教程
Dec 06 PHP
PHP和XSS跨站攻击的防范
Apr 17 PHP
PHP strtok()函数的优点分析
Mar 02 PHP
php cookie的操作实现代码(登录)
Dec 29 PHP
ajax在joomla中的原生态应用代码
Jul 19 PHP
php写的AES加密解密类分享
Jun 20 PHP
php将字符串全部转换成大写或者小写的方法
Mar 17 PHP
PHP基于堆栈实现的高级计算器功能示例
Sep 15 PHP
php中青蛙跳台阶的问题解决方法
Oct 14 PHP
PHP实现的用户注册表单验证功能简单示例
Feb 25 PHP
Laravel框架模型的创建及模型对数据操作示例
May 07 PHP
php提高脚本性能的4个技巧
Aug 18 PHP
php广告加载类用法实例
Sep 23 #PHP
php实现根据url自动生成缩略图的方法
Sep 23 #PHP
php实现的支持imagemagick及gd库两种处理的缩略图生成类
Sep 23 #PHP
PHP图片库imagemagick安装方法
Sep 23 #PHP
安装ImageMagick出现error while loading shared libraries的解决方法
Sep 23 #PHP
php实现的支持断点续传的文件下载类
Sep 23 #PHP
php实现的click captcha点击验证码类实例
Sep 23 #PHP
You might like
php adodb操作mysql数据库
2009/03/19 PHP
PHP中输出转义JavaScript代码的实现代码
2011/04/22 PHP
php缓存技术详细总结
2013/08/07 PHP
php实现基于微信公众平台开发SDK(demo)扩展的方法
2014/12/22 PHP
js AspxButton的客户端操作
2009/06/26 Javascript
一个JS小玩意 几个属性相加不能超过一个特定值.
2009/09/29 Javascript
extjs 学习笔记(三) 最基本的grid
2009/10/15 Javascript
jQuery实现单击和鼠标感应事件
2015/02/01 Javascript
js中实现字符串和数组的相互转化详解
2016/01/24 Javascript
JavaScript事件类型中焦点、鼠标和滚轮事件详解
2016/01/25 Javascript
Node.js编写组件的三种实现方式
2016/02/25 Javascript
js实现表单及时验证功能 用户信息立即验证
2016/09/13 Javascript
JavaScript、C# URL编码、解码总结
2017/01/21 Javascript
JavaScript使用readAsDataUrl方法预览图片
2017/05/10 Javascript
AngularJS实现动态添加Option的方法
2017/05/17 Javascript
React中使用async validator进行表单验证的实例代码
2018/08/17 Javascript
详谈js的变量提升以及使用方法
2018/10/06 Javascript
Postman环境变量全局变量使用方法详解
2020/08/13 Javascript
jQuery实现移动端扭蛋机抽奖
2020/11/08 jQuery
[42:24]完美世界DOTA2联赛循环赛 LBZS vs DM BO2第一场 11.01
2020/11/02 DOTA
python 简单备份文件脚本v1.0的实例
2017/11/06 Python
Python处理菜单消息操作示例【基于win32ui模块】
2018/05/09 Python
django中forms组件的使用与注意
2019/07/08 Python
PyCharm中Matplotlib绘图不能显示UI效果的问题解决
2020/03/12 Python
python实现三种随机请求头方式
2021/01/05 Python
全球最大的瓷器、水晶和银器零售商:Replacements
2020/06/15 全球购物
怎样声明一个匿名的内部类
2016/06/01 面试题
平面设计的岗位职责
2013/11/08 职场文书
保安岗位职责
2014/02/21 职场文书
2014全国两会学习心得体会1000字
2014/03/10 职场文书
设备管理实施方案
2014/05/31 职场文书
项目负责人任命书
2014/06/04 职场文书
计算机毕业生求职信
2014/06/10 职场文书
小学教育见习总结
2015/06/23 职场文书
用Python远程登陆服务器的步骤
2021/04/16 Python
Redis源码阅读:Redis字符串SDS详解
2021/07/15 Redis