簡體   English   中英

PHP文件管理系統

[英]PHP File Management System

我們需要創建一個文件管理界面,該界面與基於cakephp構建的客戶端當前網站集成。

文件管理器必須僅允許用戶查看他們也具有權限的文件。

該用戶將能夠上傳(任何大小)文件,並讓其他用戶下載這些文件(如果允許的話)。

對於我們可以購買的許多文件管理系統來說,這不是問題,但是我找不到能與他們當前登錄系統集成的系統。 客戶端只希望用戶登錄一次即可訪問其用戶CP和文件。 據我所知,我們唯一的選擇是自己構建文件管理界面。

我們允許使用PHP上傳的選項有哪些? 我了解我們需要提高php上傳限制,但是php / apache是​​否有一個上限?

如果相關的話,文件的最大容量可能約為150MB,但是在某些情況下,文件大小可能會更大。

另外,Linux服務器上文件上傳/控制的作用和不應該做什么?

我想我沒有真正的“特定”問題,但希望對從何入手以及我們將遇到的一些典型陷阱提出一些建議。

實際上,文件管理非常容易。 以下是一些建議,可能會為您指明正確的方向。

首先,如果這是負載平衡的Web服務器,則需要稍微增加復雜度才能將文件放置在一個公共位置。 如果是這樣,請ping通,我很樂意將相同情況下使用的超輕型文件服務器/客戶端發送給您。

為了允許更大的上傳量,您需要影響一些變量。 我建議使用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>

建築:

創建一個數據庫表,其中存儲有關每個文件的一些信息。

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 

什么是Owner_FieldOwner_Key 一種簡單的方式來說明文件是什么“實體”。 在這種特定情況下,有多種類型的文件正在上載。 就您而言,一個簡單的User_ID字段就足夠了。

存儲所有者的目的是使您可以限制誰可以下載和刪除文件。 這對於保護下載至關重要。

這是一個示例類 ,可用於接受從瀏覽器上傳的文件。 當然,您需要對其進行修改以適合。

關於以下代碼,需要注意一些事項。 由於這是與應用程序服務器和文件服務器一起使用的,因此需要進行一些替換。

  1. 任何出現的App::CallAPI(...)都需要替換為執行“相同操作”的一個查詢或一組查詢。
  2. 任何出現的App::$FS->...都需要用PHP中的正確文件處理功能替換,例如move_uploaded_filereadfile等。

這里是。 請記住,這里有一些功能可讓您查看給定用戶擁有的文件,刪除文件等等。 底部有更多說明...

<?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']);
        }
    }

}

筆記:

請記住,此類不實現安全性。 它假定在​​調用FileClient::Serve(...)等之前,調用者具有已驗證的Owner_Field和Owner_Key。

太晚了,因此,如果其中某些步驟沒有意義,請發表評論。 祝您有個愉快的夜晚,希望對您有所幫助。

PS。 用戶界面可以是簡單的表和文件上載字段等。或者您可能很喜歡使用Flash上​​載器...

我建議看看以下社區提供的CakePHP代碼示例:

這是個好選擇。 它要求您安裝PC客戶端和單個文件php服務器。 但是它運行很快!

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM