Rumah > Artikel > pembangunan bahagian belakang > 【请点评】写的一个OOP面向对象的类,功能:扫描整站文件夹!
功能:扫描整站所有指定类型的文件,并且收集其路径存储到数据库。(用于筛选出大小为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>');
你的类不能独立运行,这是最大的毛病
这个感觉不像个类,倒像把面向过程硬生生改成面向对象(单例)