65.9K
CodeProject 正在变化。 阅读更多。
Home

PHPFM:一个单文件、响应式文件管理器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (9投票s)

2017年1月28日

CPOL

1分钟阅读

viewsIcon

39410

downloadIcon

955

为您的 PHP 网站提供的非常快速的文件管理器

GitLab URL: https://gitlab.com/windowssnt/PHPFileManager。 欢迎贡献!

引言

我尝试过几个文件管理器,但它们似乎都非常复杂。 为什么不自己做一个呢?

  • 单个文件。 只需将 phpfm.php 复制到您的根目录,就完成了。
  • Bootstrap, jQuery, BootBox, Font Awesome, Chosen, Data Tables
  • 如果通过 HTTP 访问,则使用 HTTP digest 登录,如果通过 HTTPS 访问,则使用表单登录。
  • 支持多个用户,具有特定的根文件夹和每个文件夹的读/写访问权限选项。
  • 将用户保存到自身或 SQLite 数据库。
  • 创建文件夹。
  • 上传文件。
  • 以 zip 格式上传多个文件。
  • 下载文件。
  • 以 zip 格式下载多个文件。
  • 删除文件/文件。

登录

如果您处于 HTTPS 连接中,登录是一个简单的 Bootstrap 表单

对于第一次登录,请以 root 用户名,不使用密码登录。

密码以 sha-1 哈希形式保存,并提供注销选项(终止会话)。

如果您处于 HTTP 连接中,密码将以明文形式保存,但身份验证方法是 HTTP digest,以避免传输原始密码。

$users 数组

$users = array('root' => array('admin' => '1','password' => '',
'root' => '.','access' => array('.' => 2)))

access”数组本身是一个数组,其中包含目录和访问级别对(1 读,2 写)。

为了安全起见,PHPFM 从不允许访问包含“..”或以“/”开头的任何文件。

如果将用户保存到自身,则使用一个简单的函数来序列化 users 数组

function LoadUsers()
{
    global $users;

    if (count($users) == 1 && $users['root']['password'] == "")
        return "\$users = array();\r\n";

    $u = "\$users = array(\r\n";
    $i = 0;
    foreach($users as $username => $user)
    {
        if ($i > 0)
            $u .= ",\r\n";
        $acc = "array(";// array("." => 2)
        $ii = 0;
        foreach($user['access'] as $acxd => $acx)
        {
            if ($ii > 0)
                $acc .= ",";
            $acc .= sprintf("'%s' => %s",$acxd,$acx);
            $ii++;
        }
        $acc .= ")";
        $u .= sprintf("'%s' => array('admin' => '%s','password' => 
        '%s','root' => '%s','access' => %s)",
        $username,$user['admin'],$user['password'],$user['root'],$acc);
        $i++;
    }

    $u .= "\r\n);";
    return $u;
}

如果保存到数据库,则使用 SQLite。 创建用户(或更改根密码)后,您将无法再在两种方法之间切换。

接口

文件或 Zip 上传

使用一个简单的 PHP $_FILE 表单

if (array_key_exists("zip",$_POST) && $_POST['zip'] == 1)
{
    $zip = new ZipArchive;
    $zip->open($tempfile);
    $nf = $zip->numFiles;
    for($i = 0; $i < $nf ; $i++)
    {
        $fn2 = $zip->getNameIndex($i);
        if (strstr($fn2,"..") !== false || strstr($fn2,"/") === $fn2)
        {
        unlink($tempfile);
        $_SESSION['error'] = "File contains files with .. or /, not allowed.";
        die;
        }
     }
    $zip->extractTo($cr);
}
else
{
   $dbdata = file_get_contents($tempfile);
   $full = $_SESSION['current'].'/'.$fn;
   file_put_contents($full,$dbdata);
}
unlink($tempfile);

文件或 Zip 下载

对于单个文件,使用直接的 application/octet-stream

header('Content-Description: Download');
header('Content-Type: application/octet-stream');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header(sprintf("Content-disposition: attachment;filename=%s",basename($u)));
header('Content-Length: ' . filesize($u));
readfile($u);

或者 ZIP 下载,同时检查权限

    $what = $_POST['massdownload'];
    $fuf = "";
    $dp = strrpos($_POST['massdownload'],"/");
    if ($dp === false)
        $fuf = $_SESSION['current'].'/';
    else
        $fuf = substr($_GET['down'],0,$dp);

    if (AccessType($fuf) === 0)
    {
        $_SESSION['error'] = "Read access denied to folder <b>$root</b>.";
    }
    else
    {
        $arr = array();
        $items = explode(',',$what);
        foreach($items as $item)
        {
            if (strstr($item,"/") == $item)
                die;
            if (strstr($item,"..") !== false)
                die;
            $full = $_SESSION['current'].'/'.$item;
            enumDir($full,$arr);
        }

        $tz = tempnam(".","zip");
        if (file_exists($tz))
            unlink($tz);
        $tz .= ".zip";
        if (file_exists($tz))
            unlink($tz);
        $zip = new ZipArchive;
        $zipo = $zip->open($tz,ZipArchive::CREATE | ZipArchive::OVERWRITE);
        foreach($arr as $a)
        {
            if (is_dir($a))
                continue;
            $rs = $zip->addFile($a,substr($a,2));
            if (!$rs)
                die;
        }
        $zip->close();
        Down($tz,1);
        unlink($tz);
        die;
    }

玩得开心!

历史

  • 2017年1月23日:首次发布
© . All rights reserved.