[英]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_Field
和Owner_Key
? 一種簡單的方式來說明文件是什么“實體”。 在這種特定情況下,有多種類型的文件正在上載。 就您而言,一個簡單的User_ID
字段就足夠了。
存儲所有者的目的是使您可以限制誰可以下載和刪除文件。 這對於保護下載至關重要。
這是一個示例類 ,可用於接受從瀏覽器上傳的文件。 當然,您需要對其進行修改以適合。
關於以下代碼,需要注意一些事項。 由於這是與應用程序服務器和文件服務器一起使用的,因此需要進行一些替換。
App::CallAPI(...)
都需要替換為執行“相同操作”的一個查詢或一組查詢。 App::$FS->...
都需要用PHP中的正確文件處理功能替換,例如move_uploaded_file
, readfile
等。 這里是。 請記住,這里有一些功能可讓您查看給定用戶擁有的文件,刪除文件等等。 底部有更多說明...
<?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服務器。 但是它運行很快!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.