首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > PHP >

两份PHP程序代码对比,大家认为其编程水平都如何样?censor.class.php

2013-01-28 
两份PHP程序代码对比,大家认为其编程水平都怎么样?censor.class.php功能:一个censor审核提交字符串的类(附

两份PHP程序代码对比,大家认为其编程水平都怎么样?censor.class.php
功能:一个censor审核提交字符串的类(附加在DEDECMS里面)
两份不同的作品,同样的一种功能,大家评比一下~认为他们的水平如何?
如果你是主考官,你会如何选择?为什么?


涉及MySQL数据表:gk_info_censor


mysql> desc gk_info_censor;
+-------------+----------------------+------+-----+---------+----------------+
| Field       | Type                 | Null | Key | Default | Extra          |
+-------------+----------------------+------+-----+---------+----------------+
| id          | smallint(6) unsigned | NO   | PRI | NULL    | auto_increment |
| admin       | varchar(15)          | NO   |     |         |                |
| type        | smallint(6)          | NO   |     | 1       |                |
| find        | varchar(255)         | NO   | UNI |         |                |
| replacement | varchar(255)         | NO   |     |         |                |
| extra       | varchar(255)         | NO   |     |         |                |
| count       | int(11)              | NO   |     | 0       |                |
| updatetime  | int(11)              | NO   |     | NULL    |                |
| tids        | mediumtext           | NO   |     | NULL    |                |
| enable      | tinyint(1)           | NO   |     | -1      |                |
+-------------+----------------------+------+-----+---------+----------------+


10 rows in set (0.01 sec)



1.censor.class1.php

<?php

/* censorStatus: {banned} {censor} {replace} */

class Censor
{
  public $censorCount;
  public $censorData;
  public $censorLimit;

  function __construct()
  {
    $this->censorCount = NULL;
    $this->censorCount->replace = 0;
    $this->censorCount->censor = 0;
    $this->censorCount->Banned = 0;
    $this->censorLimit = 120;
    $this->censorData = $this->GetCensorData();
  }

  /*
  select * from
  */
  function GetCensorData()
  {
    static $censorData = NULL;
    if($censorData !== NULL) return $censorData;

    $censorData->banned = null;
    $censorData->censor = null;
    $censorData->replace= null;
    $censorData->repalce->from = $censorData->replace->to = null;

    global $dsql;
    $sql = "SELECT * FROM gk_info_censor WHERE replacement!='' AND `enable`=1 ";
    $dsql->Execute('s',$sql);
    while ($row = $dsql->GetArray('s'))
    {
      switch ($row['replacement'])
      {
        case '{banned}':  $censorData->banned[] = $row['find']; break;//banned
        case '{censor}':  $censorData->censor[] = $row['find']; break;//censor
        default:          $censorData->replace->from[] = $row['find'];//replace
                          $censorData->replace->to[] = $row['replacement'];
                          break;
      }
    }
    return $censorData;
  }

  function check( &$string )
  {
    if($this->banned( $string) < 1)
    {
      if($this->censor( $string ) < 1)
      {
        $this->replace( $string );
      }
    }
  }

  //替换级别 返回替换匹配个数
  function replace(&$subject)
  {
    if(empty($this->censorData->replace->from) || empty($this->censorData->replace->to)) return 0;

    $i = 0;
    while ($arrFROM = array_slice($this->censorData->replace->find,$i,$this->censorLimit))


    {
      $i += $this->censorLimit;
      if(empty($arrFrom)) continue;
      $arrTo = array_slice($this->censorData->replace->to,$i,$this->censorLimit);
      #$subject = preg_replace($arrFrom, $arrTo, $subject);
      array_map('str_replace',$arrFrom,$arrTo,$subject);
    }
  }

  //审核级别 返回审核匹配个数
  function censor(&$subject)
  {
    if(empty($this->censorData->censor)) return 0;

    $i = $count = 0;
    while ($arr = array_slice($this->censorData->censor,$i,$this->censorLimit))
    {
      preg_match_all('#'.split('|',$arr).'#', $subject, $matches);
      if($matches) $count += count($matches[0]);
      $i += $this->censorLimit;
    }
    $this->censorCount->banned += $count;
    return $count;
  }

  //彻底禁止 返回禁止匹配个数
  function banned(&$subject)
  {
    if(empty($this->censorData->banned)) return 0;

    $i = $count = 0;
    while($arr = array_slice($this->censorData->banned,$i,$this->censorLimit))
    {
      preg_match_all('#'.split('|',$arr).'#', $subject, $matches);
      if($matches) $count += count($matches[0]);
      $i+= $this->censorLimit;
    }
    $this->censorCount->banned += $count;
    return $count;
  }

  //审核级别 banned,censor,pass
  function censorLevel()
  {
    if($this->censorCount->banned > 0 ) return 'banned';
    if($this->censorCount->censor > 0 ) return 'censor';
    return 'pass';
  }
}




2.censor.class2.php
<?php

/* censorStatus: {banned} {censor} {replace} */

class Censor
{
  public $censorCount_banned;
  public $censorCount_censor;
  public $censorCount_replace;
  public $censorData;
  public $censorLimit;
  public $cachePath;

  function __construct()
  {
    $this->censorCount_replace = 0;
    $this->censorCount_censor = 0;
    $this->censorCount_banned = 0;
    $this->censorLimit = 120;
    $this->cachePath = DEDEDATA.'/cache_censor.php';
    $this->censorData = $this->GetCensorData();
  }


  function GetCensorData()
  {
    if(defined('CENSORDATA_LOADED'))
    {


      if(empty($censorData)) ShowMsg("ERROR:CENSOR数据不存在!");
      return $censorData;
    } elseif( file_exists($this->cachePath) && filesize($this->cachePath) > 1024) {
      include $this->cachePath;
      if(empty($this->cachePath)) ShowMsg('Error: censor cache file size error!');
      return $censorData;
    }

    $censorData = array();
    $censorData['banned'] = array();
    $censorData['censor'] = array();
    $censorData['repalce']= array();

    global $dsql;
    $sql = "SELECT * FROM gk_info_censor WHERE replacement!='' AND `enable`=1 ";
    $dsql->Execute('s',$sql);
    while ($row = $dsql->GetArray('s'))
    {
      switch ($row['replacement'])
      {
        case '{banned}':  $censorData[banned][] = $row['find']; break;//banned
        case '{censor}':  $censorData[censor][] = $row['find']; break;//censor
        default:          $censorData[replace][$row['find']]=$row['replacement'];break;//replace
      }
    }

    #$cachePath = DEDEDATA.'/cache_censor.php';
    $cacheCode = "<"."?php\n";
    $cacheCode .= "\n#Make Time:".date("Y-m-d H:i:s");
    $cacheCode .= "\n#Make File:".__FILE__."(Line:".__LINE__.")";
    $cacheCode .= "\n#notice! do not modify me!\n\n";

    $cacheCode .= "\ndefine('CENSORDATA_LOADED',TRUE);";
    $cacheCode .= "\n\$censorData=array();";
    $cacheCode .= "\n\$censorData[banned] = null;";
    $cacheCode .= "\n\$censorData[censor] = null;";
    $cacheCode .= "\n\$censorData[replace]= null;";

    $cacheCode .= $this->makecode($censorData[banned],'censorData[banned]');
    $cacheCode .= $this->makecode($censorData[censor],'censorData[censor]');
    foreach ($censorData[replace] as $k => $v) {
      $cacheCode .= "\n\$censorData[replace]['".addslashes($k)."']= '".addslashes ($v)."';";
    }
    $cacheCode .= "\n\n?".">";

    $fp = @fopen($this->cachePath,"w") or die(" Tag Engine Create File FALSE! ");
    fwrite($fp,$cacheCode);
    fclose($fp);
    return $censorData;
  }

  function makecode($data,$varname)
  {
    $i=0;
    $codestring = '';
    while($arr = array_slice($data,$i,$this->censorLimit,true))


    {
      $codestring .= "\n\$".$varname."[] = '/". addcslashes( implode('|',$arr),"{}[]/.()'"*" )."/i';";
      $i += $this->censorLimit;
    }
    return $codestring;
  }

  function check( &$string )
  {
    $this->banned($string);
    $this->censor($string);
    $this->replace($string);
    /*
    if($this->banned( $string) < 1)
    {
      if($this->censor( $string ) < 1)
      {
        $this->replace( $string );
      }
    }
    */
  }

  //替换级别 返回替换匹配个数
  function replace(&$subject)
  {
    if(empty($this->censorData[replace])) return 0;

    foreach($this->censorData[replace] as $from => $to)
    {
      $subject = str_replace($from,$to,$subject);
    }
  }

  //审核级别 返回审核匹配个数
  function censor(&$subject)
  {
    if(empty($this->censorData[censor])) return 0;

    $count = 0;
    foreach($this->censorData[censor] as $pattern)
    {
      preg_match_all($pattern, $subject, $matches);
      if($matches) $count += count($matches[0]);
    }
    $this->censorCount_censor += $count;
    return $count;
  }

  //彻底禁止 返回禁止匹配个数
  function banned(&$subject)
  {
    if(empty($this->censorData[banned])) return 0;

    $count = 0;
    foreach($this->censorData[banned] as $pattern)
    {
      preg_match_all($pattern, $subject, $matches);
      if($matches) $count += count( $matches[0] );
      //print_r($matches);
    }
    $this->censorCount_banned += $count;
    return $count;
  }

  //审核级别 banned,censor,pass
  function censorLevel()
  {
    if($this->censorCount_banned > 0 ) return 'banned';
    if($this->censorCount_censor > 0 ) return 'censor';
    return 'pass';
  }
}




[解决办法]
别的先不说
至少第二段代码 29 行处的
      if(empty($censorData)) ShowMsg("ERROR:CENSOR数据不存在!");
      return $censorData;


是错误的
[解决办法]
都很牛逼的样子
[解决办法]
都垃圾的很!
[解决办法]


路过~
[解决办法]
你就逗大家玩呢....

来人啊...脱出去那个....对了,你是男是女?



[解决办法]

//这一段建议包装一下。 如果你喜欢使用缓存策略,这块代码需要封装起来,便于重用!~
//读和取,都封起来~
    if(defined('CENSORDATA_LOADED') && !empty($GLOBALS['censorData']))
    {
      return $GLOBALS['censorData'];
    } elseif( file_exists($this->cachePath) && filesize($this->cachePath) > 1024) {
      include $this->cachePath;
      if(!empty($censorData)) return $censorData;
    }

    #$cachePath = DEDEDATA.'/cache_censor.php';


    $cacheCode = "<"."?php\n";
    $cacheCode .= "\n#Make Time:".date("Y-m-d H:i:s");
    $cacheCode .= "\n#Make File:".__FILE__."(Line:".__LINE__.")";
    $cacheCode .= "\n#notice! do not modify me!\n\n";
 
    $cacheCode .= "\ndefine('CENSORDATA_LOADED',TRUE);";
    $cacheCode .= "\n\$censorData=array();";
    $cacheCode .= "\n\$censorData['banned'] = null;";
    $cacheCode .= "\n\$censorData['censor'] = null;";
    $cacheCode .= "\n\$censorData['replace']= null;";
 
    $cacheCode .= $this->makecode($censorData['banned'],"censorData['banned']");
    $cacheCode .= $this->makecode($censorData['censor'],"censorData['censor']");


[解决办法]
明显就是一个人写的,命名风格都一样。

几点不足:

1 “banned”这种常量字符串,在class中我更喜欢用const来声明。如果它们是枚举值,应该定义一个数组来存放全部枚举值,类似创建了一个哈希表,这样更加严谨。还有那些写死的数字,都应该使用const来定义,调用时self::XXX;这样改的时候直接从类的头部改一个地方下面全改了。

2 虽然php没规定变量提前声明,但既然选择使用class,就应该规范一些。这样会造成一大堆警告。提前显示声明所有使用的变量,不要用隐式声明。

3 完全是php4的class用法,没有封装的概念!所有方法全都默认的public,就没有private或protected。如果这个类是个单一功能类。那么应该只有一个public方法负责把最后结果返回给外部,外部只需要调用这一个方法就够了。其他的全部private,由这个方法在类内部去调用那些private或protected方法,如果此类以后仍有扩展的空间,需要继承的话,应该用protected。

4 使用了全局变量,我认为在没有namespace的大多数情况下,都不应该使用全局变量,尤其是这种名称短的,什么$dsql,$GLOBALS['censorData']d的,尽量用参数传进来也不要用全局变量。

5 $this->censorData[replace]这种极为初级的问题也有。不加引号php解释器会尝试把replace当成常量去解释,这种写法比加上引号效率低很多。

6 $fp = @fopen($this->cachePath,"w") or die(" Tag Engine Create File FALSE! ");竟然还有这种代码。。。就不能事先判断下file_exists并且is_writable下。非要用那个@符号。

7 这代码好蛋疼。
function check( &$string ) {
    if($this->banned( $string) < 1)
    {
      if($this->censor( $string ) < 1)
      {
        $this->replace( $string );
      }
    }
  }

function banned(&$subject)
对于这种引用传递的。可以使用链式语法,这些方法都不需要再返回那个数量,而是在方法内部做数量检查,然后都返回$this。
然后这里就可以用链式语法了。

function banned(&$subject){
    ...
    return $this;
}

function check( &$string ) {
    $this->banned( $string)
            ->censor( $string )
            ->replace( $string )
            ->
}



总结,对oop的理解很肤浅。除非用的是php4,否则这样使用class还不如直接写一堆函数。明显是为了用class而用的class,根本没有理解oop的精髓。有些方法可以拆开几个方法。虽然有些啰嗦,但那样才符合抽象,松耦合的概念。包括你改过之后的代码,仅仅是实现了功能而已,从oop的角度讲,还欠缺很多。
[解决办法]
各有千秋,不过,总体看第一个比较好

热点排行