2009-07-02 154 views
0

我们需要创建一个文件管理界面,该界面可以与建立在cakephp上的客户端当前网站集成。PHP文件管理系统

文件管理器只能让用户看到他们也有权限的文件。

用户将能够上传文件(任何大小)并让其他用户下载这些文件(如果权限允许)。

对于我们可以购买的许多文件管理系统而言,这并不是问题,但是我无法找到的文件管理系统将与他们当前在系统中的日志进行集成。客户端只需要用户登录一次即可访问其用户CP及其文件。所以就我所见,我们唯一的选择就是自己建立一个文件管理界面。

什么是我们必须允许使用PHP上传的一些选项?我知道我们需要增加php上传限制,但是有没有php/apache允许的上限?

如果相关文件的文件大小约为150MB,但可能会出现文件大小较大的情况。

另外在Linux服务器上文件上传/控制的做什么和不该做什么?

我想我没有真正的“具体”问题,但希望提供一些建议,从哪里开始,以及我们遇到的一些典型缺陷。

+0

你能不能修改FMS使用相同的凭证,它不应该是很难用PHP? – 2009-07-02 05:38:43

+0

我一直无法找到允许进行此类修改的文件。 – user103219 2009-07-02 05:49:33

回答

9

实际上,文件管理非常简单。这里有一些建议可能会指向正确的方向。

首先,如果这是一个负载平衡的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上​​传...

+0

非常感谢,这比我期待的要多得多!这将需要我几个经过它,但我相信这回答了我所有的问题:) – user103219 2009-07-02 15:31:04

0

这里是不错的选择。它需要你安装一个PC客户端和一个文件php服务器。但它运行速度很快!

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