简体   繁体   English

PHP文件管理系统

[英]PHP File Management System

We need to create a file management interface that integrates with the clients current website built on cakephp. 我们需要创建一个文件管理界面,该界面与基于cakephp构建的客户端当前网站集成。

The file manager must only let the users see the files that they have permissions too. 文件管理器必须仅允许用户查看他们也具有权限的文件。

The user will be able to upload files(of any size) and have other users download those files (if permissions allow). 该用户将能够上传(任何大小)文件,并让其他用户下载这些文件(如果允许的话)。

This is no problem for many file management systems that we can purchase but none that I can find will integrate with their current log in system. 对于我们可以购买的许多文件管理系统来说,这不是问题,但是我找不到能与他们当前登录系统集成的系统。 The client only wants the users to log in once to access their user CP and their files. 客户端只希望用户登录一次即可访问其用户CP和文件。 So as far as I can see our only option is to build a file management interface ourselves. 据我所知,我们唯一的选择是自己构建文件管理界面。

What are some of the options that we have to allow uploads using PHP? 我们允许使用PHP上传的选项有哪些? I understand that we need to increase the php upload limit, but is there a ceiling that php/apache will allow? 我了解我们需要提高php上传限制,但是php / apache是​​否有一个上限?

The files will likely cap out at approximately 150MB if that is relevant, however there may be situations where the file sizes will be larger. 如果相关的话,文件的最大容量可能约为150MB,但是在某些情况下,文件大小可能会更大。

Also what are the do's and don'ts of file upload/control on a Linux server? 另外,Linux服务器上文件上传/控制的作用和不应该做什么?

I suppose I have no real 'specific' questions but would like some advise on where to start and some of the typical pitfalls we will run into. 我想我没有真正的“特定”问题,但希望对从何入手以及我们将遇到的一些典型陷阱提出一些建议。

File management is quite easy, actually. 实际上,文件管理非常容易。 Here are some suggestions that may point you in the right direction. 以下是一些建议,可能会为您指明正确的方向。

First of all, if this is a load balanced web server situation, you'll need to step up the complexity a little in order to put the files in one common place. 首先,如果这是负载平衡的Web服务器,则需要稍微增加复杂度才能将文件放置在一个公共位置。 If that's the case, ping me and I'll be happy to send you our super-light file server/client we use for that same situation. 如果是这样,请ping通,我很乐意将相同情况下使用的超轻型文件服务器/客户端发送给您。

There are a few variables you will want to affect in order to allow larger uploads. 为了允许更大的上传量,您需要影响一些变量。 I recommend using apache directives to limit these changes to a particular file: 我建议使用apache指令将这些更改限制为特定文件:

<Directory /home/deploy/project/uploader>
    php_value max_upload_size "200M"
    php_value post_max_size "200M"
    php_value max_input_time "1800"

    # this one depends on how much processing you are doing to the file
    php_value memory_limit "32M" 
</Directory>

Architecture: 建筑:

Create a database table that stores some information about each file. 创建一个数据库表,其中存储有关每个文件的一些信息。

CREATE TABLE `File` (
  `File_MNID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `Owner_Field` enum('User.User_ID', 'Resource.Resource_ID') NOT NULL,
  `Owner_Key` int(10) unsigned NOT NULL,
  `ContentType` varchar(64) NOT NULL,
  `Size` int(10) NOT NULL,
  `Hash` varchar(40) NOT NULL,
  `Name` varchar(128) NOT NULL,
  PRIMARY KEY (`File_MNID`),
  KEY `Owner` (`Owner_Field`,`Owner_Key`)
) ENGINE=InnoDB 

What is Owner_Field and Owner_Key ? 什么是Owner_FieldOwner_Key A simple way to say what "entity" owns the file. 一种简单的方式来说明文件是什么“实体”。 In this specific case there were multiple types of files being uploaded. 在这种特定情况下,有多种类型的文件正在上载。 In your case, a simple User_ID field may be adequate. 就您而言,一个简单的User_ID字段就足够了。

The purpose of storing the owner is so that you can restrict who can download and delete the file. 存储所有者的目的是使您可以限制谁可以下载和删除文件。 That will be crucial for protecting the downloads. 这对于保护下载至关重要。

Here is a sample class that can be used to accept the file uploads from the browser. 这是一个示例类 ,可用于接受从浏览器上传的文件。 You'll need to modify it to suit, of course. 当然,您需要对其进行修改以适合。

There are a few things to note about the following code. 关于以下代码,需要注意一些事项。 Since this is used with an Application Server and a File Server, there are a few things to "replace". 由于这是与应用程序服务器和文件服务器一起使用的,因此需要进行一些替换。

  1. Any occurrences of App::CallAPI(...) will need to be replaced with a query or set of queries that do the "same thing". 任何出现的App::CallAPI(...)都需要替换为执行“相同操作”的一个查询或一组查询。
  2. Any occurrences of App::$FS->... will need to be replaced with the correct file handling functions in PHP such as move_uploaded_file , readfile , etc... 任何出现的App::$FS->...都需要用PHP中的正确文件处理功能替换,例如move_uploaded_filereadfile等。

Here it is. 这里是。 Keep in mind that there are functions here which allow you to see files owned by a given user, delete files, and so on and so forth. 请记住,这里有一些功能可让您查看给定用户拥有的文件,删除文件等等。 More explanation at the bottom... 底部有更多说明...

<?php

class FileClient
{
    public static $DENY     = '/\.ade$|\.adp$|\.asp$|\.bas$|\.bat$|\.chm$|\.cmd$|\.com$|\.cpl$|\.crt$|\.exe$|\.hlp$|\.hta$|\.inf$|\.ins$|\.isp$|\.its$| \.js$|\.jse$|\.lnk$|\.mda$|\.mdb$|\.mde$|\.mdt,\. mdw$|\.mdz$|\.msc$|\.msi$|\.msp$|\.mst$|\.pcd$|\.pif$|\.reg$|\.scr$|\.sct$|\.shs$|\.tmp$|\.url$|\.vb$|\.vbe$|\.vbs$|vsmacros$|\.vss$|\.vst$|\.vsw$|\.ws$|\.wsc$|\.wsf$|\.wsh$/i';

    public static $MAX_SIZE = 5000000;

    public static function SelectList($Owner_Field, $Owner_Key)
    {
        $tmp = App::CallAPI
        (
            'File.List',
            array
            (
                'Owner_Field' => $Owner_Field,
                'Owner_Key' => $Owner_Key,
            )
        );

        return $tmp['Result'];
    }

    public static function HandleUpload($Owner_Field, $Owner_Key, $FieldName)
    {
        $aError = array();

        if(! isset($_FILES[$FieldName]))
            return false;
        elseif(! is_array($_FILES[$FieldName]))
            return false;
        elseif(! $_FILES[$FieldName]['tmp_name'])
            return false;
        elseif($_FILES[$FieldName]['error'])
            return array('An unknown upload error has occured.');

        $sPath = $_FILES[$FieldName]['tmp_name'];
        $sHash = sha1_file($sPath);
        $sType = $_FILES[$FieldName]['type'];
        $nSize = (int) $_FILES[$FieldName]['size'];
        $sName = $_FILES[$FieldName]['name'];

        if(preg_match(self::$DENY, $sName))
        {
            $aError[] = "File type not allowed for security reasons.  If this file must be attached, please add it to a .zip file first...";
        }

        if($nSize > self::$MAX_SIZE)
        {
            $aError[] = 'File too large at $nSize bytes.';
        }

        // Any errors? Bail out.
        if($aError)
        {
            return $aError;
        }


        $File = App::CallAPI
        (
            'File.Insert',
            array
            (
                'Owner_Field'        => $Owner_Field,
                'Owner_Key'            => $Owner_Key,
                'ContentType'        => $sType,
                'Size'                => $nSize,
                'Hash'                => $sHash,
                'Name'                => $sName,
            )
        );

        App::InitFS();
        App::$FS->PutFile("File_" . $File['File_MNID'], $sPath);

        return $File['File_MNID'];

    }

    public static function Serve($Owner_Field, $Owner_Key, $File_MNID)
    {
        //Also returns the name, content-type, and ledger_MNID
        $File    = App::CallAPI
        (
            'File.Select',
            array
            (
                'Owner_Field'     => $Owner_Field,
                'Owner_Key'     => $Owner_Key,
                'File_MNID'     => $File_MNID
            )
        );

        $Name     = 'File_' . $File['File_MNID'] ;

        //Content Header for that given file
        header('Content-disposition: attachment; filename="' . $File['Name'] . '"');
        header("Content-type:'" . $File['ContentType'] . "'");

        App::InitFS();
        #TODO
        echo App::$FS->GetString($Name);

    }

    public static function Delete($Owner_Field, $Owner_Key, $File_MNID)
    {

        $tmp = App::CallAPI
        (
            'File.Delete',
            array
            (
                'Owner_Field' => $Owner_Field,
                'Owner_Key' => $Owner_Key,
                'File_MNID' => $File_MNID,
            )
        );

        App::InitFS();
        App::$FS->DelFile("File_" . $File_MNID);
    }

    public static function DeleteAll($Owner_Field, $Owner_Key)
    {
        foreach(self::SelectList($Owner_Field, $Owner_Key) as $aRow)
        {
            self::Delete($Owner_Field, $Owner_Key, $aRow['File_MNID']);
        }
    }

}

Notes: 笔记:

Please keep in mind that this class DOES NOT implement security. 请记住,此类不实现安全性。 It assumes that the caller has an authenticated Owner_Field and Owner_Key before calling FileClient::Serve(...) etc... 它假定在​​调用FileClient::Serve(...)等之前,调用者具有已验证的Owner_Field和Owner_Key。

It's a bit late, so if some of this doesn't make sense, just leave a comment. 太晚了,因此,如果其中某些步骤没有意义,请发表评论。 Have a great evening, and I hope this helps some. 祝您有个愉快的夜晚,希望对您有所帮助。

PS. PS。 The user interface can be simple tables and file upload fields, etc.. Or you could be fancy and use a flash uploader... 用户界面可以是简单的表和文件上载字段等。或者您可能很喜欢使用Flash上​​载器...

I recommend having a look at the following community-contributed CakePHP code examples: 我建议看看以下社区提供的CakePHP代码示例:

here is good choice. 这是个好选择。 It requires you install a PC client and a single file php server. 它要求您安装PC客户端和单个文件php服务器。 But it runs fast! 但是它运行很快!

http://the-sync-star.com/ http://the-sync-star.com/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM