本文實例講述了TP3.2.3框架文件上傳操作。分享給大家供大家參考,具體如下:
上傳表單
在ThinkPHP中使用上傳功能無需進行特別處理。例如,下面是一個帶有附件上傳的表單提交:
1
2
3
4
5
|
< form action = "__URL__/upload" enctype = "multipart/form-data" method = "post" > < input type = "text" name = "name" /> < input type = "file" name = "photo" /> < input type = "submit" value = "提交" > </ form > |
注意,要使用上傳功能 你的表單需要設(shè)置 enctype="multipart/form-data"
多文件上傳支持
如果需要使用多個文件上傳,只需要修改表單,把
1
|
< input type = 'file' name = 'photo' > |
改為
1
2
3
|
< input type = 'file' name = 'photo1' > < input type = 'file' name = 'photo2' > < input type = 'file' name = 'photo3' > |
或者
1
2
3
|
< input type = 'file' name = 'photo[]' > < input type = 'file' name = 'photo[]' > < input type = 'file' name = 'photo[]' > |
兩種方式的多附件上傳系統(tǒng)的文件上傳類都可以自動識別。
上傳操作
ThinkPHP文件上傳操作使用Think\Upload類,假設(shè)前面的表單提交到當(dāng)前控制器的upload方法,我們來看下upload方法的實現(xiàn)代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public function upload(){ $upload = new \Think\Upload(); // 實例化上傳類 $upload ->maxSize = 3145728 ; // 設(shè)置附件上傳大小 $upload ->exts = array ( 'jpg' , 'gif' , 'png' , 'jpeg' ); // 設(shè)置附件上傳類型 $upload ->rootPath = './Uploads/' ; // 設(shè)置附件上傳根目錄 $upload ->savePath = '' ; // 設(shè)置附件上傳(子)目錄 // 上傳文件 $info = $upload ->upload(); if (! $info ) { // 上傳錯誤提示錯誤信息 $this ->error( $upload ->getError()); } else { // 上傳成功 $this ->success( '上傳成功!' ); } } |
上傳類對圖片文件的上傳安全做了支持,如果企圖上傳非法的圖像文件,系統(tǒng)會提示 非法圖像文件。 為了更好的使用上傳功能,建議你的服務(wù)器開啟finfo模塊支持
上傳參數(shù)
在上傳操作之前,我們可以對上傳的屬性進行一些設(shè)置,Upload類支持的屬性設(shè)置包括:
屬性 | 描述 |
---|---|
maxSize | 文件上傳的最大文件大?。ㄒ宰止?jié)為單位),0為不限大小 |
rootPath | 文件上傳保存的根路徑 |
savePath | 文件上傳的保存路徑(相對于根路徑) |
saveName | 上傳文件的保存規(guī)則,支持?jǐn)?shù)組和字符串方式定義 |
saveExt | 上傳文件的保存后綴,不設(shè)置的話使用原文件后綴 |
replace | 存在同名文件是否是覆蓋,默認(rèn)為false |
exts | 允許上傳的文件后綴(留空為不限制),使用數(shù)組或者逗號分隔的字符串設(shè)置,默認(rèn)為空 |
mimes | 允許上傳的文件類型(留空為不限制),使用數(shù)組或者逗號分隔的字符串設(shè)置,默認(rèn)為空 |
autoSub | 自動使用子目錄保存上傳文件 默認(rèn)為true |
subName | 子目錄創(chuàng)建方式,采用數(shù)組或者字符串方式定義 |
hash | 是否生成文件的hash編碼 默認(rèn)為true |
callback | 檢測文件是否存在回調(diào),如果存在返回文件信息數(shù)組 |
上面的屬性可以通過兩種方式傳入:
實例化傳入
我們可以在實例化的時候直接傳入?yún)?shù)數(shù)組,例如:
1
2
3
4
5
6
7
8
9
10
|
$config = array ( 'maxSize' => 3145728, 'rootPath' => './Uploads/' , 'savePath' => '' , 'saveName' => array ( 'uniqid' , '' ), 'exts' => array ( 'jpg' , 'gif' , 'png' , 'jpeg' ), 'autoSub' => true, 'subName' => array ( 'date' , 'Ymd' ), ); $upload = new \Think\Upload( $config ); // 實例化上傳類 |
關(guān)于saveName和subName的使用后面我們會有詳細(xì)的描述。
動態(tài)賦值
支持在實例化后動態(tài)賦值上傳參數(shù),例如:
1
2
3
4
5
6
7
8
|
$upload = new \Think\Upload(); // 實例化上傳類 $upload ->maxSize = 3145728; $upload ->rootPath = './Uploads/' ; $upload ->savePath = '' ; $upload ->saveName = array ( 'uniqid' , '' ); $upload ->exts = array ( 'jpg' , 'gif' , 'png' , 'jpeg' ); $upload ->autoSub = true; $upload ->subName = array ( 'date' , 'Ymd' ); |
上面的設(shè)置和實例化傳入的效果是一致的。
上傳文件信息
設(shè)置好上傳的參數(shù)后,就可以調(diào)用Think\Upload類的upload方法進行附件上傳,如果失敗,返回false,并且用getError方法獲取錯誤提示信息;如果上傳成功,就返回成功上傳的文件信息數(shù)組。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
$upload = new \Think\Upload(); // 實例化上傳類 $upload ->maxSize = 3145728 ; // 設(shè)置附件上傳大小 $upload ->exts = array ( 'jpg' , 'gif' , 'png' , 'jpeg' ); // 設(shè)置附件上傳類型 $upload ->rootPath = './Uploads/' ; // 設(shè)置附件上傳根目錄 $upload ->savePath = '' ; // 設(shè)置附件上傳(子)目錄 // 上傳文件 $info = $upload ->upload(); if (! $info ) { // 上傳錯誤提示錯誤信息 $this ->error( $upload ->getError()); } else { // 上傳成功 獲取上傳文件信息 foreach ( $info as $file ){ echo $file [ 'savepath' ]. $file [ 'savename' ]; } } |
每個文件信息又是一個記錄了下面信息的數(shù)組,包括:
屬性 | 描述 |
---|---|
key | 附件上傳的表單名稱 |
savepath | 上傳文件的保存路徑 |
name | 上傳文件的原始名稱 |
savename | 上傳文件的保存名稱 |
size | 上傳文件的大小 |
type | 上傳文件的MIME類型 |
ext | 上傳文件的后綴類型 |
md5 | 上傳文件的md5哈希驗證字符串 僅當(dāng)hash設(shè)置開啟后有效 |
sha1 | 上傳文件的sha1哈希驗證字符串 僅當(dāng)hash設(shè)置開啟后有效 |
文件上傳成功后,就可以使用這些文件信息來進行其他的數(shù)據(jù)操作,例如保存到當(dāng)前數(shù)據(jù)表或者單獨的附件數(shù)據(jù)表。
例如,下面表示把上傳信息保存到數(shù)據(jù)表的字段:
1
2
3
4
5
6
7
|
$model = M( 'Photo' ); // 取得成功上傳的文件信息 $info = $upload ->upload(); // 保存當(dāng)前數(shù)據(jù)對象 $data [ 'photo' ] = $info [0][ 'savename' ]; $data [ 'create_time' ] = NOW_TIME; $model ->add( $data ); |
單文件上傳
upload方法支持多文件上傳,有時候,我們只需要上傳一個文件,就可以使用Upload類提供的uploadOne方法上傳單個文件,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public function upload(){ $upload = new \Think\Upload(); // 實例化上傳類 $upload ->maxSize = 3145728 ; // 設(shè)置附件上傳大小 $upload ->exts = array ( 'jpg' , 'gif' , 'png' , 'jpeg' ); // 設(shè)置附件上傳類型 $upload ->rootPath = './Uploads/' ; // 設(shè)置附件上傳根目錄 // 上傳單個文件 $info = $upload ->uploadOne( $_FILES [ 'photo1' ]); if (! $info ) { // 上傳錯誤提示錯誤信息 $this ->error( $upload ->getError()); } else { // 上傳成功 獲取上傳文件信息 echo $info [ 'savepath' ]. $info [ 'savename' ]; } } |
uploadOne方法上傳成功后返回的文件信息和upload方法的區(qū)別是只有單個文件信息的一維數(shù)組。
上傳文件的命名規(guī)則
上傳文件的命名規(guī)則(saveName)用于確保文件不會產(chǎn)生沖突或者覆蓋的情況。命名規(guī)則的定義可以根據(jù)你的業(yè)務(wù)邏輯來調(diào)整,不是固定的。例如,如果你采用時間戳的方式來定義命名規(guī)范,那么在同時上傳多個文件的時候可能產(chǎn)生沖突(因為同一秒內(nèi)可以上傳多個文件),因此你需要根據(jù)你的業(yè)務(wù)需求來設(shè)置合適的上傳命名規(guī)則。這里順便來說下saveName參數(shù)的具體用法。
一、采用函數(shù)方式
如果傳入的字符串是一個函數(shù)名,那么表示采用函數(shù)動態(tài)生成上傳文件名(不包括文件后綴),例如:
1
2
3
4
|
// 采用時間戳命名 $upload ->saveName = 'time' ; // 采用GUID序列命名 $upload ->saveName = 'com_create_guid' ; |
也可以采用用戶自定義函數(shù)
1
2
|
// 采用自定義函數(shù)命名 $upload ->saveName = 'myfun' ; |
默認(rèn)的命名規(guī)則設(shè)置是采用uniqid函數(shù)生成一個唯一的字符串序列。
saveName的值支持?jǐn)?shù)組和字符串兩種方式,如果是只有一個參數(shù)或者沒有參數(shù)的函數(shù),直接使用字符串設(shè)置即可,如果需要傳入額外的參數(shù),可以使用數(shù)組方式,例如:
1
2
3
4
|
// 采用date函數(shù)生成命名規(guī)則 傳入Y-m-d參數(shù) $upload ->saveName = array ( 'date' , 'Y-m-d' ); // 如果有多個參數(shù)需要傳入的話 可以使用數(shù)組 $upload ->saveName = array ( 'myFun' , array ( '__FILE__' , 'val1' , 'val2' )); |
如果需要使用上傳的原始文件名,可以采用__FILE__傳入,所以上面的定義規(guī)則,最終的結(jié)果是 myFun('上傳文件名','val1','val2')執(zhí)行的結(jié)果。
二、直接設(shè)置上傳文件名
如果傳入的參數(shù)不是一個函數(shù)名,那么就會直接當(dāng)做是上傳文件名,例如:
1
|
$upload ->saveName = time(). '_' .mt_rand(); |
表示上傳的文件命名采用時間戳加一個隨機數(shù)的組合字符串方式。
當(dāng)然,如果覺得有必要,你還可以固定設(shè)置一個上傳文件的命名規(guī)則,用于固定保存某個上傳文件。
1
|
$upload ->saveName = 'ThinkPHP' ; |
三、保持上傳文件名不變
如果你想保持上傳的文件名不變,那么只需要設(shè)置命名規(guī)范為空即可,例如:
1
|
$upload ->saveName = '' ; |
一般來說不建議保持不變,因為會導(dǎo)致相同的文件名上傳后被覆蓋的情況。
子目錄保存
saveName只是用于設(shè)置文件的保存規(guī)則,不涉及到目錄,如果希望對上傳的文件分子目錄保存,可以設(shè)置autoSub和subName參數(shù)來完成,例如:
1
2
3
|
// 開啟子目錄保存 并以日期(格式為Ymd)為子目錄 $upload ->autoSub = true; $upload ->subName = array ( 'date' , 'Ymd' ); |
可以使用自定義函數(shù)來保存,例如:
1
2
3
|
// 開啟子目錄保存 并調(diào)用自定義函數(shù)get_user_id生成子目錄 $upload ->autoSub = true; $upload ->subName = 'get_user_id' ; |
和saveName參數(shù)一樣,subName的定義可以采用數(shù)組和字符串的方式。
注意:如果get_user_id函數(shù)未定義的話,會直接以get_user_id字符串作為子目錄的名稱保存。
子目錄保存和文件命名規(guī)則可以結(jié)合使用。
上傳驅(qū)動
上傳類可以支持不同的環(huán)境,通過相應(yīng)的上傳驅(qū)動來解決,默認(rèn)情況下使用本地(Local)上傳驅(qū)動,當(dāng)然,你還可以設(shè)置當(dāng)前默認(rèn)的上傳驅(qū)動類型,例如:
1
2
3
4
5
6
7
|
'FILE_UPLOAD_TYPE' => 'Ftp' , 'UPLOAD_TYPE_CONFIG' => array ( 'host' => '192.168.1.200' , //服務(wù)器 'port' => 21, //端口 'timeout' => 90, //超時時間 'username' => 'ftp_user' , //用戶名 'password' => 'ftp_pwd' , //密碼 ), |
表示當(dāng)前使用Ftp作為上傳類的驅(qū)動,上傳的文件會通過FTP傳到指定的遠程服務(wù)器。
也可以在實例化上傳類的時候指定,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
$config = array ( 'maxSize' = 3145728, 'rootPath' = './Uploads/' , 'savePath' = '' , 'saveName' = array ( 'uniqid' , '' ), 'exts' = array ( 'jpg' , 'gif' , 'png' , 'jpeg' ), 'autoSub' = true, 'subName' = array ( 'date' , 'Ymd' ), ); $ftpConfig = array ( 'host' => '192.168.1.200' , //服務(wù)器 'port' => 21, //端口 'timeout' => 90, //超時時間 'username' => 'ftp_user' , //用戶名 'password' => 'ftp_pwd' , //密碼 ); $upload = new \Think\Upload( $config , 'Ftp' , $ftpConfig ); // 實例化上傳類 |
希望本文所述對大家基于ThinkPHP框架的PHP程序設(shè)計有所幫助。
原文鏈接:https://blog.csdn.net/luyaran/article/details/70321642