php文件管理器

最近在研究DEDECMS,感觉它的文件管理器很不过,想想这个模块在以后的开发中可能会用到,所以就将其从系统中剥离出来,便于以后使用。

其实文件管理器涉及的内容也就是php对文件的操作,相对于其他语言来说,php来写文件管理器要容易简单的多,不想java一样,要很繁琐的操作。

先来看看它的入口文件index.php

$root=$_SERVER[DOCUMENT_ROOT];
$cmspath="$root/resource/file_manager";
$activepath=$_GET['activepath'];

if(!isset($activepath)) $activepath=$cmspath;

$inpath = "";
$activepath = str_replace("..", "", $activepath);
$activepath = preg_replace("#^\/{1,}#", "/", $activepath);
if($activepath == "/") $activepath = "";

if($activepath == "") $inpath = $cmspath;
else $inpath = $activepath;

$activeurl = $activepath;

include('view/index_view.htm');
$activepath在整个模块总一直都存在,它表示当前的文件路径,对于index来说,可以表示web根目录,也可以表示web应用的根目录,在这里可以自行进行设置

再来看加载的view/index_view.htm





文件管理器




	read())!==false)
		{
			if($file!="." && $file!=".." && !is_dir("$inpath/$file"))
			{
				@$filesize=filesize("$inpath/$file");
				$filesize=$filesize/1024; //b->kb
				$filetime=filemtime("$inpath/$file");//文件创建时间
				$filetime=date("Y-m-d H:i:s",$filetime);//格式化时间
				if($filesize<0.1)
				{
					list($ty1,$ty2)=explode(".",$filesize);
					$filesize=$ty1.".".substr($ty2,0,2);
				}
				else
				{
					list($ty1,$ty2)=explode(".",$filesize);
					$filesize=$ty1.".".substr($ty2,0,1);
				}
			}
			if($file==".")
			{
				continue;
			}
			else if($file=="..")
			{
				if($activepath=="")
				{
					continue;
				}
				$tmp=preg_replace("#[\/][^\/]*$#i", "", $activepath);
				$line="\n";
				$dirs[]=$line;
			} 
			
			else if(is_dir("$inpath/$file"))  
			{
				if(preg_match("#^_(.*)$#i" , $file)) continue;
				if(preg_match("#^\.(.*)$#i" , $file)) continue;
				$line = "\n";
				$dirs[] = $line;
			}
			else if(preg_match("#\.(gif|png)#i",$file))  //如果是GIF或PNG
			{
				$line = "\n";
			$files[] = $line;
			}
			else if(preg_match("#\.(jpg)#i", $file)) //如果是jpg图片类型
			{
				$line = "\n";
				$files[] = $line;
			}
			else if(preg_match("#\.(swf|fla|fly)#i", $file)) //如果是flash类型
			{
				$line = "\n";
				$files[] = $line;
			}
			else if(preg_match("#\.(zip|rar|tar.gz)#i",$file)) //压缩文件
			{
				$line = "\n";
				$files[] = $line;
			}
			else if(preg_match("#\.(exe)#i", $file)) //文件类型为可执行文件
			{
				$line = "\n";
			   $files[] = $line;
			}
			else if(preg_match("#\.(mp3|wma)#i",$file)) //音频文件
			{
				$line = "\n";
				$files[] = $line;
			}	
			else if(preg_match("#\.(wmv|api)#i",$file)) //视频文件
			{
				$line = "\n";
				$files[] = $line;
			}
			else if(preg_match("#\.(rm|rmvb)#i",$file)) //视频文件rm rmvb
			{
				$line = "\n";
			$files[] = $line;
			}
			else if(preg_match("#\.(txt|inc|pl|cgi|asp|xml|xsl|aspx|cfm)#",$file)) //常用文本文件类型
			{
				$edurl = "view/file_manage_view.php?fmdo=edit&filename=".urlencode($file)."&activepath=".urlencode($activepath);
				$line = "\n";
				$files[] = $line;
			}
			else if(preg_match("#\.(htm|html)#i",$file)) //网页类型
			{
				$edurl = "view/file_manage_view.php?fmdo=edit&filename=".urlencode($file)."&activepath=".urlencode($activepath);
				$line = "\n";
				$files[] = $line;
			}
			else if(preg_match("#\.(php)#i",$file)) //php脚本类型
			{
				$edurl = "view/file_manage_view.php?fmdo=edit&filename=".urlencode($file)."&activepath=".urlencode($activepath);
				$line = "\n";
				$files[] = $line;
			}
			else if(preg_match("#\.(js)#i",$file))  //js脚本类型
			{
				$edurl = "view/file_manage_view.php?fmdo=edit&filename=".urlencode($file)."&activepath=".urlencode($activepath);
				$line = "\n";
				$files[] = $line;
			}
			else if(preg_match("#\.(css)#i",$file)) //css
			{
				$edurl = "view/file_manage_view.php?fmdo=edit&filename=".urlencode($file)."&activepath=".urlencode($activepath);
				$line = "\n";
				$files[] = $line;
			}
			else
			{
				$line = "\n";
				$files[] = $line;
			}
		}
		$dh->close();//关闭文件流
		foreach($dirs as $dir)
		{
			echo $dir;
		}
		foreach($files as $file)
		{
			echo $file;
		}
	?>
	
文件名 文件大小 最后修改时间 操作
上级目录 当前目录:$activepath   [图片浏览器]
$file     [改名]   [删除]
$file $filesize KB $filetime [改名]   [删除]   [移动]
$file $filesize KB $filetime [改名]   [删除]   [移动]
$file $filesize KB $filetime [改名]   [删除]   [移动]
$file $filesize KB $filetime [改名]   [删除]   [移动]
$file $filesize KB $filetime [改名]   [删除]   [移动]
$file $filesize KB $filetime [改名]   [删除]   [移动]
$file $filesize KB $filetime [改名]   [删除]   [移动]
$file $filesize KB $filetime [改名]   [删除]   [移动]
$file $filesize KB $filetime [编辑]   [改名]   [删除]   [移动]
$file $filesize KB $filetime [编辑]   [改名]   [删除]   [移动]
$file $filesize KB $filetime [编辑]   [改名]   [删除]   [移动]
$file $filesize KB $filetime [编辑]   [改名]   [删除]   [移动]
$file $filesize KB $filetime [编辑]   [改名]   [删除]   [移动]
$file $filesize KB $filetime [改名]   [删除]   [移动]
[根目录]   [新建文件]   [新建目录]   [文件上传]   [空间检查]   

这个文件主要来设置文件管理器的视图及样式,根据不同类型的文件,文件的图标是不同的,文件的操作功能是不同的,呈现出来的效果如下:


这样基本就可以得到文件目录的视图了,接下来是文件的操作:

文件的操作和文件的操作视图分别写在file_manage_control.php和file_manage_view.php中

file_manage_control.php

read())
    {
        if($infile=="."||$infile=="..")
        {
            continue;
        }
        else if(is_file("$indir/$infile"))
        {
            unlink("$indir/$infile");
        }
        else
        {
            RmDirFiles("$indir/$infile");
        }
    }
    $dh->close();
    rmdir($indir);
    return 1;
}

/*---------------
修改文件名
rename($oldname,$filename)
is_writable($filename)
----------------*/
if($fmdo=="rename")
{
    $oldfile=$activepath.'/'.$_POST['oldfilename'];
    $newfile=empty($_POST['newfilename']) ? $oldfile : $activepath.'/'.$_POST['newfilename'];
    if(($newfile!=$oldfile) && is_writable($oldfile))
    {
        if(rename($oldfile,$newfile)) 
            ShowMsg("文件名修改成功","../index.php?activepath=".$activepath); 
    }
    else
        ShowMsg("请检查文件名是否为空,或者文件是否有写入权限!","../index.php?activepath=".$activepath);
}
/*---------------
编辑文件
stripslashes($str)反引用一个引用字符串(一般也就是用来去掉字符串中\)
----------------*/
else if($fmdo=="edit")
{
    $str=$_POST['str'];//获取编辑框的内容
    $filename=str_replace("..","",$filename);//替换文件中的".."字符串
    $file=$activepath.'/'.$filename;//文件的绝对地址
    $str=stripslashes($str);
    $fp=fopen($file,"w");//以写的方式打开文件,并返回文件句柄
    if(fwrite($fp,$str))//写入文件(覆盖掉原有的文本内容)
    {
        ShowMsg("修改成功","../index.php?activepath=".$activepath);
    }
    else
    {
        ShowMsg("禁止修改!","../index.php?activepath=".$activepath);
    }
    fclose($fp);//关闭文件句柄
    
}
else if($fmdo=="del")
{
    $file=$activepath.'/'.$filename;
    if(is_file($file))
    {
        if(unlink($file))
        {
            ShowMsg("删除成功","../index.php?activepath=".$activepath);
        }
        else
        {
            ShowMsg("删除失败,请检查系统权限!","../index.php?activepath=".$activepath);
        }
        $t="文件";
    } 
    else
    {
        $t="目录";
        if(RmDirFiles($file))
        {
            ShowMsg("目录删除成功","../index.php?activepath=".$activepath);
        }
        else
        {
            ShowMsg("目录删除失败","../index.php?activepath=".$activepath);
        }
    }
}
else if($fmdo=="move")
{
    $newpath=$_POST['newpath'];
    if($newpath!="" && !preg_match("#\.\.#", $newpath))
    {
        $oldfile=$activepath."/$filename";
        $newpath=str_replace("\\", "/", $newpath);
        $newpath=preg_replace("#\/{1,}#" , "/" , $newpath);
        $newpath=$activepath."/$newpath";
        if(is_readable($oldfile) && is_readable($newpath) && is_writable($newpath))
        {
            if(is_dir($newpath))
            {
                $flag=copy($oldfile,$newpath."/$filename") ? 1 : 0;
            }
            else
            {
                mkdir($newpath);//mode在Windows下被忽略
                $flag=copy($oldfile , $newpath."/$filename") ? 1 : 0;
            }
            unlink($oldfile);
        }
    }
    if($flag==1)
        ShowMsg("文件移动成功","../index.php?activepath=".$activepath);
    else
        ShowMsg("文件移动失败","../index.php?activepath=".$activepath);
}
else if($fmdo=="newdir")
{
    $newpath=$_POST['newpath'];
    if(!empty($newpath))
    {
        $newdirpath=$activepath."/$newpath";
        if(mkdir($newdirpath))
        {
            ShowMsg("目录创建成功","../index.php?activepath=".$activepath);
        } 
        else
            ShowMsg("目录创建失败","../index.php?activepath=".$activepath);
    }    
}
else if($fmdo=="upload")
{
    for($i=1;$i<50;$i++)
    {
        $upfile="upfile".$i;
        if($_FILES[$upfile]['error']>0)
        {
            continue;
        }
        else
        {
            move_uploaded_file($_FILES[$upfile]['tmp_name'], $activepath.'/'.$_FILES[$upfile]['name']);
        }
    }
    ShowMsg("文件上传成功","../index.php?activepath=".$activepath);
}
else if($fmdo=="space")
{
    if($activepath=="")
    {
        $ecpath = "所有目录";
    }
    else
    {
        $ecpath = $activepath;
    }
    $titleinfo = "目录 $ecpath 空间使用状况:
"; $wintitle = "文件管理"; $wecome_info = "文件管理::空间大小检查 [文件浏览器]"; $activepath=$cfg_basedir.$activepath; $space = new SpaceUse; $space->checksize($activepath); $total=$space->totalsize; $totalkb=$space->setkb($total); $totalmb=$space->setmb($total); $win = new OxWindow(); $win->Init("","js/blank.js","POST"); $win->AddTitle($titleinfo); $win->AddMsgItem("  $totalmb M
  $totalkb KB
  $total 字节"); $winform = $win->GetWindow(""); $win->Display(); } ?>

不同的操作对应不同的视图,如果每个视图都给出一个文件的话,未免有点太繁琐,而且整个过程也是在不断的重复,定义一个良好的文件操作的类,会大大减轻我们的工作提高效率

文件操作视图模板类oxwindow.class.php

myWin .= "\r\n";
        $this->formName = $formname;
        $this->myWin .= "
\r\n"; } /** * 增加隐藏域 * @param $inputName 表单域name * @param $inputValue 表单域value * @return void */ function AddHidden($inputName,$inputValue) { $this->myWin .= "\r\n"; } /** * 开始创建窗口 * @return void */ function StartWin() { $this->myWin .= "\r\n"; } /** * 增加一个两列的行 * * @access public * @param string $iname 名称 * @param string $ivalue 值 * @return string */ function AddItem($iname, $ivalue) { $this->myWinItem .= "\r\n"; $this->myWinItem .= "\r\n"; $this->myWinItem .= "\r\n"; $this->myWinItem .= "\r\n"; } /** * 增加一个单列的消息行 * * @access public * @param string $ivalue 短消息值 * @param string $height 消息框高度 * @param string $col 显示列数 * @return void */ function AddMsgItem($ivalue, $height="100", $col="2") { if($height!=""&&$height!="0") { $height = " height='$height'"; } else { $height=""; } if($col!=""&&$col!=0) { $colspan="colspan='$col'"; } else { $colspan=""; } $this->myWinItem .= "\r\n"; $this->myWinItem .= "\r\n"; $this->myWinItem .= "\r\n"; } /** * 增加单列的标题行 * * @access public * @param string $title 标题 * @param string $col 列 * @return string */ function AddTitle($title, $col="2") { // global $cfg_plus_dir; if($col!=""&&$col!="0") { $colspan="colspan='$col'"; } else { $colspan=""; } $this->myWinItem .= "\r\n"; $this->myWinItem .= "\r\n"; $this->myWinItem .= "\r\n"; } /** * 结束Window * * @param bool $isform * @return void */ function CloseWin($isform=true) { if(!$isform) { $this->myWin .= "
$iname$ivalue
$ivalue
$title
\r\n"; } else { $this->myWin .= "
\r\n"; } } /** * 增加自定义JS脚本 * * @param string $scripts * @return void */ function SetCheckScript($scripts) { // strpos()返回一个字符串在另一个字符串中第一次出现的位置 $pos = strpos($this->myWin,$this->tmpCode); if($pos > 0)//myWin中确实有tmpCode { //substr_replace(要检查的字符串,要替换的字符串,替换的位置,替换的长度) $this->myWin = substr_replace($this->myWin,$scripts,$pos,strlen($this->tmpCode)); } } /** * 获取窗口 * * @param string $wintype 菜单类型 * @param string $msg 短消息 * @param bool $isform 是否是表单 * @return string */ function GetWindow($wintype="save", $msg="", $isform=true) { // global $cfg_plus_dir; $this->StartWin(); $this->myWin .= $this->myWinItem; if($wintype!="") { if($wintype!="hand") { $this->myWin .= "
"; } else { if($msg!='') { $this->myWin .= "$msg"; } else { $this->myWin .= ''; } } } $this->CloseWin($isform); return $this->myWin; } /** * 显示页面 * * @access public * @param string $modfile 模型模板 * @return string */ function Display($modfile="") { global $welcome_info ,$wintitle; if(empty($welcome_info)) { $welcome_info = "通用对话框:"; } if($modfile=='') { require_once("../view/plus/win_templet.htm"); } else { require_once($modfile); } } } /** * 显示一个不带表单的普通提示 * * @access public * @param string $msg 消息提示信息 * @param string $title 提示标题 * @return string */ function ShowMsgWin($msg, $title) { $win = new OxWindow(); $win->Init(); $win->mainTitle = "系统提示:"; $win->AddTitle($title); $win->AddMsgItem("
$msg
"); $winform = $win->GetWindow("hand"); $win->Display(); } ?>

操作视图模板

文件编辑模板:file_edit.htm





文件管理器




 ◇文件管理 >> 修改/新建文件
修改/新建文件:
工作目录 (空白表示根目录 ,不允许用 “..” 形式的路径)
文件名称 (不允许用 “..” 形式的路径)
   

文件上传模板:file_upload.htm





文件上传





文件上传
[返回目录]
 
文件1:
          

视图模板:win_templet.htm




<?php echo $wintitle; ?>



 
myWin; ?>

developed by sevend


接下来是文件操作视图:file_manage_view.php

文件浏览器]";
    $win = new OxWindow();
    $win->Init("file_manage_control.php","js/blank.js","POST");
    $win->AddHidden("fmdo",$fmdo);
    $win->AddHidden("activepath",$activepath);
    $win->AddHidden("filename",$filename);
    $win->AddTitle("更改文件名,当前路径:$ndirstring");
    $win->AddItem("旧名称:","");
    $win->AddItem("新名称:","");
    $winform = $win->GetWindow("ok");
    $win->Display();
    // echo $win->myWin;
}
//修改文件内容
else if($fmdo=="edit")
{
    if(!isset($backurl))
    {
        $backurl="";
    }
    if(!isset($ishead))
    {
        $ishead="";
    }
    $activepath=str_replace("..", "", $activepath);
    $filename=str_replace("..","",$filename);
    $file=$activepath.'/'.$filename;
    $content="";
    if(is_file($file))
    {
        $fp=fopen($file,"r");
        $content=fread($fp,filesize($file));
        fclose($fp);
        $content=htmlspecialchars($content);//html格式转换
    }
    $contentView="\r\n";
    require_once("plus/file_edit.htm");
}
//删除文件
else if($fmdo=="del")
{
    $wintitle = " 文件管理";
    $wecome_info = " 文件管理::删除文件 [文件浏览器]";
    $win = new OxWindow();
    $win->Init("file_manage_control.php","js/blank.js","POST");
    $win->AddHidden("fmdo",$fmdo);
    $win->AddHidden("activepath",$activepath);
    $win->AddHidden("filename",$filename);
    if(@is_dir($activepath."/$filename"))
    {
        $wmsg = "你确信要删除目录:$filename 吗?";
    }
    else
    {
        $wmsg = "你确信要删除文件:$filename 吗?";
    }
    $win->AddTitle("删除文件确认");
    $win->AddMsgItem($wmsg,"50");
    $winform = $win->GetWindow("ok");
    $win->Display();
}
else if($fmdo=="move")
{
    $wintitle = " 文件管理";
    $wecome_info = " 文件管理::移动文件 [文件浏览器]";
    $win = new OxWindow();
    $win->Init("file_manage_control.php","js/blank.js","POST");
    $win->AddHidden("fmdo",$fmdo);
    $win->AddHidden("activepath",$activepath);
    $win->AddHidden("filename",$filename);
    $win->AddTitle("新位置前面不加'/'表示相对于当前位置,加'/'表示相对于根目录。");
    $win->AddItem("被移动文件:",$filename);
    $win->AddItem("当前位置:",$activepath);
    $win->AddItem("新位置:","");
    $winform = $win->GetWindow("ok");
    $win->Display();
}
else if($fmdo=="newdir")
{
    if($activepath=="") $activepathname="根目录";
    else $activepathname=$activepath;
    $wintitle = " 文件管理";
    $wecome_info = " 文件管理::新建目录 [文件浏览器]";
    $win = new OxWindow();
    $win->Init("file_manage_control.php","js/blank.js","POST");
    $win->AddHidden("fmdo",$fmdo);
    $win->AddHidden("activepath",$activepath);
    $win->AddTitle("当前目录 $activepathname ");
    $win->AddItem("新目录:","");
    $winform = $win->GetWindow("ok");
    $win->Display(); 
}
else if($fmdo=="newfile")
{
    $filename="file.txt";
    $contentView = "\r\n";
    require_once("plus/file_edit.htm");
}
else if($fmdo=="upload")
{
    require_once("plus/file_upload.htm");
}
else if($fmdo=="space")
{
    if($activepath=="")
    {
        $ecpath = "所有目录";
    }
    else
    {
        $ecpath = $activepath;
    }
    $titleinfo = "目录 $ecpath 空间使用状况:
"; $wintitle = "文件管理"; $wecome_info = "文件管理::空间大小检查 [文件浏览器]"; // $activepath=$cfg_basedir.$activepath; $size=0; $size=getDirSize($activepath); if($size>pow(2,10)) { $sizekb=round($size/pow(1024,1),2); } $sizemb=round($sizekb/1024,2); $str=$size." 字节
".$sizekb." KB
".$sizemb." MB
"; $win = new OxWindow(); $win->Init("","js/blank.js","POST"); $win->AddTitle($titleinfo); $win->AddMsgItem($str); $winform = $win->GetWindow(""); $win->Display(); } function getDirSize($dirpath) { global $size; if(is_file($dirpath)) { $size+=filesize($dirpath); } else { $dh=dir($dirpath); while($infile=$dh->read()) { if($infile=="."||$infile=="..") { continue; } else if(is_file("$dirpath/$infile")) { $size+=filesize("$dirpath/$infile"); } else { getDirSize("$dirpath/$infile"); } } $dh->close(); } return $size; } ?>

这样文件管理器基本算是完成了,我们再增加一个消息提示的类,让它变得更加完善

show_msg.php

\r\n\r\n温馨提示\r\n\r\n";
    $htmlhead .= "\r\n\r\n\r\n
\r\n\r\n
\r\n\r\n\r\n"; $litime = ($limittime==0 ? 1000 : $limittime); $func = ''; if($gourl=='-1') { if($limittime==0) $litime = 5000; $gourl = "javascript:history.go(-1);"; } if($gourl=='' || $onlymsg==1) { $msg = ""; } else { //当网址为:close::objname 时, 关闭父框架的id=objname元素 if(preg_match('/close::/',$gourl)) { $tgobj = trim(preg_replace('/close::/', '', $gourl)); $gourl = 'javascript:;'; $func .= "window.parent.document.getElementById('{$tgobj}').style.display='none';\r\n"; } $func .= " var pgo=0; function JumpUrl(){ if(pgo==0){ location='$gourl'; pgo=1; } }\r\n"; $rmsg = $func; $rmsg .= "document.write(\"
"; $rmsg .= "
提示
\");\r\n"; $rmsg .= "document.write(\"

\");\r\n"; $rmsg .= "document.write(\"".str_replace("\"","“",$msg)."\");\r\n"; $rmsg .= "document.write(\""; if($onlymsg==0) { if( $gourl != 'javascript:;' && $gourl != '') { $rmsg .= "
如果你的浏览器没反应,请点击这里..."; $rmsg .= "
\");\r\n"; $rmsg .= "setTimeout('JumpUrl()',$litime);"; } else { $rmsg .= "
\");\r\n"; } } else { $rmsg .= "

\");\r\n"; } $msg = $htmlhead.$rmsg.$htmlfoot; } echo $msg; } ?>
这样一个php的文件管理器就完全剥离出来了。

1、以前接触过php,但是从来没有系统的学习过,这次应为需要不得不再次学习。如果有其他语言,特别是C或者JAVA基础的话,php确实会很容易上手

2、php文件名的命名,如果去看那些开源项目的话,php文件的命名是很有规范的,比如说一个类文件,常常会命名为xxx.class.php,一个方法文件会命名为xxx.func.php,良好的命名会更清楚的说明这个文件的用途,作用等

3、MVC模式,在这个小的项目中也能够看到MVC模式的应用,视图(view)和控制(control)的分离,模块(model)的定义和使用。file_manage_control.php和file_manage_view.phh可以看做是control+model,每一次请求都交给它们,他们负责处理数据,并将结果转发给view,这个view也就是index_view.htm,我们会发现,实质上每次处理的结果最后呈现在我们眼前的也就是index_view.htm

4、面向对象的机制,本项目中类其实只有oxwindow.class.php它主要用来生成一个通用的对话框。方法也只有show_msg(),给每次的操作给出提示,因为对于这里并没有对于文件的操作来将其写成方法,其实将文件的每一个操作对应一个方法会更加的合理,并且在dedecms中实际上就是这么做的,这里没有这么写主要是因为每一个操作就非常具体,而且操作不是很复杂,在一定程度上并没有写成方法的必要,而且项目太小,代码维护什么的都完全不考虑,只是当做一个插件,那就没必要非要写成方法了。

你可能感兴趣的:(php)