php 过滤html标记属性类

来源:互联网 发布:汽车故障检测软件 编辑:程序博客网 时间:2024/05/17 22:41

转载自:http://blog.csdn.net/fdipzone/article/details/11884285

php 过滤html标记属性类


HtmlAttributeFilter.class.php

[php] view plain copy
  1. <?php  
  2. /** HTML Attribute Filter 
  3. *   Date:   2013-09-22 
  4. *   Author: fdipzone 
  5. *   ver:    1.0 
  6. * 
  7. *   Func: 
  8. *   public  strip              过滤属性 
  9. *   public  setAllow           设置允许的属性 
  10. *   public  setException       设置特例 
  11. *   public  setIgnore          设置忽略的标记 
  12. *   private findElements       搜寻需要处理的元素 
  13. *   private findAttributes     搜寻属性 
  14. *   private removeAttributes   移除属性 
  15. *   private isException        判断是否特例 
  16. *   private createAttributes   创建属性 
  17. *   private protect            特殊字符转义 
  18. */  
  19.   
  20. class HtmlAttributeFilter{ // class start  
  21.   
  22.     private $_str = '';            // 源字符串  
  23.     private $_allow = array();     // 允许保留的属性 例如:array('id','class','title')  
  24.     private $_exception = array(); // 特例 例如:array('a'=>array('href','class'),'span'=>array('class'))  
  25.     private $_ignore = array();    // 忽略过滤的标记 例如:array('span','img')  
  26.   
  27.   
  28.     /** 处理HTML,过滤不保留的属性 
  29.     * @param  String $str 源字符串 
  30.     * @return String 
  31.     */  
  32.     public function strip($str){  
  33.         $this->_str = $str;  
  34.   
  35.         if(is_string($this->_str) && strlen($this->_str)>0){ // 判断字符串  
  36.   
  37.             $this->_str = strtolower($this->_str); // 转成小写  
  38.   
  39.             $res = $this->findElements();  
  40.             if(is_string($res)){  
  41.                 return $res;  
  42.             }  
  43.             $nodes = $this->findAttributes($res);  
  44.             $this->removeAttributes($nodes);  
  45.         }  
  46.   
  47.         return $this->_str;  
  48.     }  
  49.   
  50.   
  51.     /** 设置允许的属性 
  52.     * @param Array $param 
  53.     */  
  54.     public function setAllow($param=array()){  
  55.         $this->_allow = $param;  
  56.     }  
  57.   
  58.   
  59.     /** 设置特例 
  60.     * @param Array $param 
  61.     */  
  62.     public function setException($param=array()){  
  63.         $this->_exception = $param;  
  64.     }  
  65.   
  66.   
  67.     /** 设置忽略的标记 
  68.     * @param Array $param 
  69.     */  
  70.     public function setIgnore($param=array()){  
  71.         $this->_ignore = $param;  
  72.     }  
  73.   
  74.   
  75.     /** 搜寻需要处理的元素 */  
  76.     private function findElements(){  
  77.         $nodes = array();  
  78.         preg_match_all("/<([^ !\/\>\n]+)([^>]*)>/i"$this->_str, $elements);  
  79.         foreach($elements[1] as $el_key => $element){  
  80.             if($elements[2][$el_key]){  
  81.                 $literal = $elements[0][$el_key];  
  82.                 $element_name = $elements[1][$el_key];  
  83.                 $attributes = $elements[2][$el_key];  
  84.                 if(is_array($this->_ignore) && !in_array($element_name$this->_ignore)){  
  85.                     $nodes[] = array('literal'=>$literal'name'=>$element_name'attributes'=>$attributes);  
  86.                 }  
  87.             }  
  88.         }  
  89.   
  90.         if(!$nodes[0]){  
  91.             return $this->_str;  
  92.         }else{  
  93.             return $nodes;  
  94.         }  
  95.     }  
  96.   
  97.   
  98.     /** 搜寻属性 
  99.     *  @param Array $nodes 需要处理的元素 
  100.     */  
  101.     private function findAttributes($nodes){  
  102.         foreach($nodes as &$node){  
  103.             preg_match_all("/([^ =]+)\s*=\s*[\"|']{0,1}([^\"']*)[\"|']{0,1}/i"$node['attributes'], $attributes);  
  104.             if($attributes[1]){  
  105.                 foreach($attributes[1] as $att_key=>$att){  
  106.                     $literal = $attributes[0][$att_key];  
  107.                     $attribute_name = $attributes[1][$att_key];  
  108.                     $value = $attributes[2][$att_key];  
  109.                     $atts[] = array('literal'=>$literal'name'=>$attribute_name'value'=>$value);  
  110.                 }  
  111.             }else{  
  112.                 $node['attributes'] = null;  
  113.             }  
  114.             $node['attributes'] = $atts;  
  115.             unset($atts);  
  116.         }  
  117.         return $nodes;  
  118.     }  
  119.   
  120.   
  121.     /** 移除属性 
  122.     *  @param Array $nodes 需要处理的元素 
  123.     */  
  124.     private function removeAttributes($nodes){  
  125.         foreach($nodes as $node){  
  126.             $node_name = $node['name'];  
  127.             $new_attributes = '';  
  128.             if(is_array($node['attributes'])){  
  129.                 foreach($node['attributes'as $attribute){  
  130.                     if((is_array($this->_allow) && in_array($attribute['name'], $this->_allow)) || $this->isException($node_name$attribute['name'], $this->_exception)){  
  131.                         $new_attributes = $this->createAttributes($new_attributes$attribute['name'], $attribute['value']);  
  132.                     }  
  133.                 }  
  134.             }  
  135.             $replacement = ($new_attributes) ? "<$node_name $new_attributes>" : "<$node_name>";  
  136.             $this->_str = preg_replace('/'.$this->protect($node['literal']).'/'$replacement$this->_str);  
  137.         }  
  138.     }  
  139.   
  140.   
  141.     /** 判断是否特例 
  142.     * @param String $element_name   元素名 
  143.     * @param String $attribute_name 属性名 
  144.     * @param Array  $exceptions     允许的特例 
  145.     * @return boolean 
  146.     */  
  147.     private function isException($element_name$attribute_name$exceptions){  
  148.         if(array_key_exists($element_name$this->_exception)){  
  149.             if(in_array($attribute_name$this->_exception[$element_name])){  
  150.                 return true;  
  151.             }  
  152.         }  
  153.         return false;  
  154.     }  
  155.   
  156.   
  157.     /** 创建属性 
  158.     * @param  String $new_attributes 
  159.     * @param  String $name 
  160.     * @param  String $value 
  161.     * @return String 
  162.     */  
  163.     private function createAttributes($new_attributes$name$value){  
  164.         if($new_attributes){  
  165.             $new_attributes .= " ";  
  166.         }  
  167.         $new_attributes .= "$name=\"$value\"";  
  168.         return $new_attributes;  
  169.     }  
  170.   
  171.   
  172.     /** 特殊字符转义 
  173.     * @param  String $str 源字符串 
  174.     * @return String 
  175.     */  
  176.     private function protect($str){  
  177.         $conversions = array(  
  178.             "^" => "\^",   
  179.             "[" => "\[",   
  180.             "." => "\.",   
  181.             "$" => "\$",   
  182.             "{" => "\{",   
  183.             "*" => "\*",   
  184.             "(" => "\(",   
  185.             "\\" => "\\\\",   
  186.             "/" => "\/",   
  187.             "+" => "\+",   
  188.             ")" => "\)",   
  189.             "|" => "\|",   
  190.             "?" => "\?",   
  191.             "<" => "\<",   
  192.             ">" => "\>"   
  193.         );  
  194.         return strtr($str$conversions);  
  195.     }  
  196.   
  197. // class end  
  198.   
  199. ?>  
demo
[php] view plain copy
  1. <?php  
  2. require('HtmlAttributeFilter.class.php');  
  3.   
  4. $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="http://www.csdn.net"><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>';  
  5.   
  6. $obj = new HtmlAttributeFilter();  
  7.   
  8. // 允许id属性  
  9. $obj->setAllow(array('id'));  
  10.   
  11. $obj->setException(array(  
  12.                     'a' => array('href'),   // a 标签允许有 href属性特例  
  13.                     'ul' => array('class')  // ul 标签允许有 class属性特例  
  14. ));  
  15.   
  16. // img 标签忽略,不过滤任何属性  
  17. $obj->setIgnore(array('img'));  
  18.   
  19. echo 'source str:<br>';  
  20. echo htmlspecialchars($str).'<br><br>';  
  21. echo 'filter str:<br>';  
  22. echo htmlspecialchars($obj->strip($str));  
  23. ?>  
原创粉丝点击