Heim  >  Artikel  >  Backend-Entwicklung  >  【请点评】写的一个OOP面向对象的类,功能:扫描整站文件夹!

【请点评】写的一个OOP面向对象的类,功能:扫描整站文件夹!

WBOY
WBOYOriginal
2016-06-23 14:06:24945Durchsuche

功能:扫描整站所有指定类型的文件,并且收集其路径存储到数据库。(用于筛选出大小为0的文件)
完成:我用的OOP来写的,不过总是感觉很多不足。以前基本上不用OOP,全都过程。求点评此“类”。
备注:其实里面有一个功能没有实现,就是支持从指定从指定目录开始扫描整站。
代码:

<?php/* * *  不支持扫描位置重设 * * $Author: $ * $Id: FileScan.class.php 2013-4-18 15:06:09Z $ **/set_time_limit(0);class FileScan {    public $startpath;    public $startdir;    public $currInfos;    public $skipCheck;    protected $webroot;    protected $outMessage;//tips messages    protected $tablename;    protected $db;    protected $handlepath;    protected $filecount;    protected $timestart;    protected $filesarr;    protected $allowFiletype;    public function __construct()    {        $this->timestart = microtime(true);        $this->webroot = ROOT_PATH;        if(substr($this->webroot,-1) == '/') $this->webroot = substr($this->webroot,0,-1);        $this->db = $GLOBALS['db'];        $this->tablename = 'mytools_filescan';        $this->handlepath = dirname(__FILE__).'/data/filescan.log';        $this->outMessage = array();        $this->fieldsarr = array(        'realpath',     'realpath_md5',        'filepath',     'is_file',      'is_dir',       'fileext',        'filesize',     'filemtime',    'filename',        'is_list','is_detail','rec_id', 'rec_type',        );        if(!$this->TableHas() && !$this->TableCreate() && !$this->TableHas())        {            $this->ShutDown('创建表失败!');        }        $this->currInfos = array();        $this->allowFiletype = array();        $this->setMessage('初始化完毕! ');    }    public function setAllowFiletype($fileext)    {        if(!in_array($fileext,$this->allowFiletype)) $this->allowFiletype[] = $fileext;    }    public function isAllowFiletype($ext)    {        if(!empty($this->allowFiletype) && !in_array($ext,$this->allowFiletype))        {            return FALSE;        }        return TRUE;    }    public function setHandle($path = '')    {       file_put_contents($this->handlepath,$path);    }    public function getHandle()    {        return file_get_contents($this->handlepath);    }    public function setMessage($message)    {        $this->outMessage[] = date('H:i:s ').$message;    }    public function ShutDown($message)    {        $this->setMessage($message);        $this->setMessage(sprintf('<hr />总计耗时:%.6f 秒!扫描到文件<b>%d</b>个',(microtime(true)-$this->timestart),$this->filecount));        foreach($this->outMessage as $k => $v)        {            echo ' '.$v.'<br />';        }        exit();    }    public function resetAll()    {        $this->TableTruncate();        $this->setHandle();        $this->setMessage('已经重设所有!');    }    public function AddRow($infos)    {        $setsql = $comma = '';        foreach($this->fieldsarr as $k)        {            if(isset($infos[$k]))            {                $setsql .= $comma."`$k`='".addslashes( htmlspecialchars( $infos[$k] ) )."'";                $comma = ',';            }        }        if(!empty($setsql))        {            $this->db->query("REPLACE INTO ".$this->tablename." SET {$setsql} ");        }    }    public function DirIsBefore($path1,$path2)    {        $path1 = strtolower($path1);        $path2 = strtolower($path2);        if($path1 == $path2) return TRUE;        $arr1 = explode('/',$path1);        $arr2 = explode('/',$path2);        $arr1Len = count($arr1);        $arr2Len = count($arr2);        $i=0;        while(true)        {            if($i > $arr1Len && $i > $arr2Len) break;            if($arr1[$i] != $arr2[$i])            {                return $this->CompareBefore($arr1[$i],$arr2[$i]);            }            $i++;        }        return FALSE;    }    //文字前后对比    public function CompareBefore($str1,$str2)    {        if($str1 == $str2) return TRUE;        $str1Length = strlen($str1);        $str2Length = strlen($str2);        $i=0;        while(true)        {            if($i > $str1Length && $i > $str2Length) break;            $k1 = $str1{$i};            $k2 = $str2{$i};            if($k1 != $k2)            {                return ( ord($k1) < ord($k2) ) ? TRUE : FALSE;            }            $i++;        }        return FALSE;    }    public function Scan($path = '')    {        //默认从根目录开始扫描        if(empty($path)) $path = $this->webroot;        $this->setHandle($path);        if(file_exists($path))        {            if(is_dir($path))            {                $this->setMessage('正扫描:'.$path.' ...');                $dh = opendir($path);                if($dh)                {                    while(($file = readdir($dh)) !== FALSE)                    {                        if($file != '.' && $file != '..')                        {                            $this->Scan($path.'/'.$file);                        }                    }                }            } elseif(is_file($path)) {                $this->Record($path);                $this->filecount++;            } else {                return;            }        }    }    public function GetFileInfos($filepath)    {        $arr = array();        if(file_exists($filepath))        {            if(is_file($filepath))            {                $a1 = pathinfo($filepath);                //过滤类型                if(!$this->isAllowFiletype($a1['extension']))                {                    return;                }                $arr['is_file'] = 1;                $arr['is_dir'] = 0;                $arr['fileext']   = $a1['extension'];                $arr['filename']  = $a1['filename'].'.'.$a1['extension'];                $arr['filemtime'] = filemtime($filepath);                $arr['filesize'] = filesize($filepath);                //商品列表页                if(preg_match('/\/product\/(\d+)\/index(-\d+)?\.html?$/i',$filepath,$matches))                {                    $arr['rec_id'] = intval($matches[1]);                    $arr['rec_type'] = 'gl';                }                //商品详细页                elseif( preg_match('/\/product\/[^\/]+\/(\d+)\.html?$/i',$filepath,$matches) ){                    $arr['rec_id'] = intval($matches[1]);                    $arr['rec_type'] = 'gd';                }            } else {                $arr['is_file'] = 0;                $arr['is_dir'] = 1;            }            $arr['filepath']    =   $filepath;            $arr['realpath']    =   realpath($filepath);            $arr['realpath_md5']=   md5($arr['realpath']);  //防止重复写入数据        }        return $arr;    }    public function fileext($filepath)    {        return substr($filepath,strrchr($filepath,'.'));    }    public function Record($filepath)    {        $infos = $this->GetFileInfos($filepath);        if(!empty($infos)) $this->AddRow($infos);        return TRUE;    }    public function TableCreate()    {        $sql =<<<EOFCREATE TABLE IF NOT EXISTS `mytools_filescan` (  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  `realpath_md5` char(32) NOT NULL,  `realpath` varchar(200) NOT NULL,  `filepath` varchar(200) NOT NULL,  `is_file` tinyint(1) NOT NULL DEFAULT '0',  `is_dir` tinyint(1) NOT NULL DEFAULT '0',  `fileext` varchar(60) NOT NULL,  `filesize` bigint(20) NOT NULL,  `filemtime` int(10) NOT NULL,  `filename` varchar(60) NOT NULL,  `rec_id` int(10) NOT NULL DEFAULT '0',  `rec_type` enum('gl','al','gd','ad') NOT NULL,  PRIMARY KEY (`id`),  UNIQUE KEY `realpath_md5` (`realpath_md5`)) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;EOF;        $this->db->query($sql);        return TRUE;    }     public function TableTruncate()    {        $this->db->query('TRUNCATE '.$this->tablename);    }    public function TableDrop()    {        $this->db->query("DROP TABLE IF EXISTS ".$this->tablename);    }    public function TableHas()    {        return $this->db->getOne('SHOW TABLES LIKE \''.$this->tablename.'\' ') == $this->tablename ? TRUE : FALSE ;    }    public function Summary()    {        $size1M = 1024*1024;        $sqlarr = array(        '总共文件数目:'   =>  ' 1 ',        '大于1M:'         =>  ' filesize > '.$size1M,        '大小为0:'        =>  ' filesize=0 ',        '<b><font color="red">危险的文件</font></b>' =>" fileext REGEXP 'exe|dll|zip|rar' ",        );        $message = $comma = '';        foreach($sqlarr as $k => $v)        {            $r = $this->db->getOne("SELECT COUNT(*) FROM ".$this->tablename." WHERE ".$v);            $message .=  $comma.$k. ' '.$r.' ';            $comma = ',';        }        $this->setMessage($message);    }    public function num_bitunit($num)    {        $bitunit = array(' B',' KB',' MB',' GB');        for ($key = 0, $count = count($bitunit); $key < $count; $key++)        {           if ($num >= pow(2, 10 * $key) - 1) // 1024B 会显示为 1KB           {               $num_bitunit_str = (ceil($num / pow(2, 10 * $key) * 100) / 100) . " $bitunit[$key]";           }        }        return $num_bitunit_str;    }    public function real_url($filepath)    {        return str_replace($this->webroot,'',$filepath);    }    public function __destruct()    {        clearstatcache();    }}




使用代码:
    if(!is_object($fscan)) $fscan = new FileScan();    $fscan->resetAll();    $fscan->setAllowFiletype('htm');    $fscan->setAllowFiletype('html');    $fscan->Scan(ROOT_PATH.'product');    $fscan->Summary();    $fscan->ShutDown('扫描完毕!<a name="bottom" id="bottom"></a><a href="?act=report">点击这里查看结果</a>!<script>window.location.hash="#bottom";</script>');


缺陷:没有实现从指定目录开始扫描整站。里面加了目录对比的,function DirIsBefore(),但是如果当前开始目录为 “/zzzzzz.zip”,然后存在文件夹“/aaaaa/aaaaaa/ddddd/”的时候,仍旧是会扫描到~ 对比没有彻底实现。
主要大家帮我看看这样是不是符合OOP规范?写法有哪些不足


回复讨论(解决方案)

你的类不能独立运行,这是最大的毛病

这个感觉不像个类,倒像把面向过程硬生生改成面向对象(单例)

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:用Zend Studio for EclipseNächster Artikel:MYSQL并发的问题