2009-07-02 8 views
0

Wir müssen eine Datei-Management-Schnittstelle erstellen, die mit den Clients aktuelle Website integriert auf CakePHP integriert.PHP-Datei-Management-System

Der Dateimanager muss den Benutzern nur die Dateien anzeigen lassen, für die sie auch Berechtigungen besitzen.

Der Benutzer kann Dateien (beliebiger Größe) hochladen und andere Benutzer können diese Dateien herunterladen (wenn die Berechtigungen dies zulassen).

Dies ist kein Problem für viele Dateiverwaltungssysteme, die wir kaufen können, aber keine, die ich finden kann, wird mit ihrem aktuellen Anmeldesystem integriert. Der Client möchte nur, dass sich die Benutzer einmal anmelden, um auf ihren Benutzer-CP und ihre Dateien zuzugreifen. Soweit ich sehen kann, besteht unsere einzige Möglichkeit darin, selbst eine Dateiverwaltungsschnittstelle zu erstellen.

Welche Optionen haben wir, um Uploads mit PHP zuzulassen? Ich verstehe, dass wir das PHP-Upload-Limit erhöhen müssen, aber gibt es eine Obergrenze, die php/apache erlaubt?

Die Dateien werden wahrscheinlich bei ungefähr 150 MB auslaufen, wenn das relevant ist, jedoch kann es Situationen geben, in denen die Dateigröße größer sein wird.

Auch was sind die Do's and Don'ts des Hochladens/Steuerns von Dateien auf einem Linux-Server?

Ich nehme an, ich habe keine wirklichen "spezifischen" Fragen, aber ich möchte einige Ratschläge, wo ich anfangen soll und einige der typischen Fallstricke, auf die wir stoßen werden.

+0

Können Sie nicht ein fms ändern die gleichen Anmeldeinformationen zu verwenden, sollte es nicht mit php schwierig sein? –

+0

Ich konnte kein fms finden, das diese Art der Modifikation erlaubt. – user103219

Antwort

9

Dateiverwaltung ist eigentlich recht einfach. Hier sind einige Vorschläge, die Sie in die richtige Richtung weisen können.

Wenn es sich um eine Situation handelt, in der sich der Lastenausgleich auswirkt, müssen Sie die Komplexität etwas erhöhen, um die Dateien an einem gemeinsamen Ort zu speichern. Wenn das der Fall ist, ping mich an und ich schicke Ihnen gerne unseren superleichten Dateiserver/Client, den wir für die gleiche Situation verwenden.

Es gibt einige Variablen, die Sie beeinflussen möchten, um größere Uploads zu ermöglichen. Ich empfehle Apache Direktiven um diese Änderungen zu einer bestimmten Datei zu begrenzen:

<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> 

Architektur:

eine Datenbanktabelle erstellen, die einige Informationen über jede Datei speichert.

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 

Was ist Owner_Field und Owner_Key? Eine einfache Möglichkeit zu sagen, welche "Entität" die Datei besitzt. In diesem speziellen Fall wurden mehrere Dateitypen hochgeladen. In Ihrem Fall kann ein einfaches Feld User_ID angemessen sein.

Der Zweck der Speicherung des Eigentümers ist, dass Sie einschränken können, wer die Datei herunterladen und löschen kann. Das wird entscheidend für den Schutz der Downloads sein.

Hier ist eine Beispielklasse, die verwendet werden kann, um die Dateiuploads vom Browser zu akzeptieren. Sie müssen es natürlich anpassen.

Es gibt ein paar Dinge, die über den folgenden Code zu beachten sind. Da dies mit einem Anwendungsserver und einem Dateiserver verwendet wird, gibt es ein paar Dinge zu "ersetzen".

  1. Alle Vorkommen von App::CallAPI(...) müssen mit einer Abfrage oder Abfrage ersetzt werden, die die „gleichen“ tun.
  2. Alle Vorkommen von App::$FS->... müssen mit den richtigen Dateihandling-Funktionen in PHP wie move_uploaded_file, readfile, etc ...

Hier ersetzt werden soll es. Beachten Sie, dass es hier Funktionen gibt, mit denen Sie Dateien anzeigen können, die einem bestimmten Benutzer gehören, Dateien löschen und so weiter. Weitere Erklärung am unteren ...

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

} 

Hinweise:

Bitte beachten Sie, dass diese Klasse Sicherheit nicht umsetzen TUT. Es geht davon aus, dass der Aufrufer eine authentifizierte Owner_Field und Owner_Key vor dem Aufruf FileClient::Serve(...) etc ...

Es ist ein bisschen spät, also, wenn einige davon keinen Sinn ergeben, lassen Sie einfach einen Kommentar. Ich wünsche Ihnen einen schönen Abend und ich hoffe, dass dies einigen hilft.

PS. Die Benutzeroberfläche kann einfache Tabellen und Datei-Upload-Felder sein, etc .. Sie können auch einen Flash-Uploader ...

+0

Wow, vielen Dank, das war viel mehr als ich erwartet hatte! Es wird mich ein paar nehmen, um es durchzugehen, aber ich glaube, das beantwortet alle meine Fragen :) – user103219

0

hier ist eine gute Wahl. Es erfordert, dass Sie einen PC-Client und einen einzelnen PHP-Server installieren. Aber es läuft schnell!

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