# 文件上傳
本篇主要介紹如何使用`ThinkPHP5`進行文件上傳及驗證。
- - [控制器定義](http://www.hmoore.net/thinkphp/thinkphp5_quickstart/179236#u63A7u5236u5668u5B9Au4E49)
- [上傳文件驗證](http://www.hmoore.net/thinkphp/thinkphp5_quickstart/179236#u4E0Au4F20u6587u4EF6u9A8Cu8BC1)
- [文件保存規則](http://www.hmoore.net/thinkphp/thinkphp5_quickstart/179236#u6587u4EF6u4FDDu5B58u89C4u5219)
- [多文件上傳](http://www.hmoore.net/thinkphp/thinkphp5_quickstart/179236#u591Au6587u4EF6u4E0Au4F20)
- [后續文件操作](http://www.hmoore.net/thinkphp/thinkphp5_quickstart/179236#u540Eu7EEDu6587u4EF6u64CDu4F5C)
## 控制器定義
> 文件上傳使用ThinkPHP5內置的`think\File`類庫,該類庫可以輕松實現文件上傳到本地服務器,如果需要上傳到其它服務器或者平臺,則需要后續調用其它類庫或者接口。
首先來創建一個Upload控制器如下:
```
<pre class="calibre18">
```
<span class="hljs-operator"><span class="hljs-number"><?php</span><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">index</span>\<span class="hljs-title">controller</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">think</span>\<span class="hljs-title">Request</span>;
<span class="hljs-operator"><span class="hljs-keyword">class</span> <span class="hljs-title">Upload</span> <span class="hljs-keyword">extends</span> \<span class="hljs-title">think</span>\<span class="hljs-title">Controller</span></span>{
<span class="hljs-comment">// 文件上傳表單</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">index</span><span class="hljs-number">()</span></span>{
<span class="hljs-keyword">return</span> <span class="hljs-regexp">$this</span>->fetch();
}
<span class="hljs-comment">// 文件上傳提交</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">up</span><span class="hljs-number">(Request <span class="hljs-regexp">$request</span>)</span></span>{
<span class="hljs-comment">// 獲取表單上傳文件</span><span class="hljs-regexp">$file</span> = <span class="hljs-regexp">$request</span>->file(<span class="hljs-string">'file'</span>);
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">empty</span>(<span class="hljs-regexp">$file</span>)) {
<span class="hljs-regexp">$this</span>->error(<span class="hljs-string">'請選擇上傳文件'</span>);
}
<span class="hljs-comment">// 移動到框架應用根目錄/public/uploads/ 目錄下</span><span class="hljs-regexp">$info</span> = <span class="hljs-regexp">$file</span>->move(ROOT_PATH . <span class="hljs-string">'public'</span> . DS . <span class="hljs-string">'uploads'</span>);
<span class="hljs-keyword">if</span> (<span class="hljs-regexp">$info</span>) {
<span class="hljs-regexp">$this</span>->success(<span class="hljs-string">'文件上傳成功:'</span> . <span class="hljs-regexp">$info</span>->getRealPath());
} <span class="hljs-keyword">else</span> {
<span class="hljs-comment">// 上傳失敗獲取錯誤信息</span><span class="hljs-regexp">$this</span>->error(<span class="hljs-regexp">$file</span>->getError());
}
}
}</span>
```
```
然后創建模板文件(`application/index/view/upload/index.html`):
```
<pre class="calibre18">
```
<span class="hljs-regexp"><!doctype html></span><span class="hljs-regexp"><<span class="hljs-operator">html</span>></span><span class="hljs-regexp"><<span class="hljs-operator">head</span>></span><span class="hljs-regexp"><<span class="hljs-operator">meta</span> <span class="hljs-operator">charset</span>=<span class="hljs-string">"UTF-8"</span>></span><span class="hljs-regexp"><<span class="hljs-operator">title</span>></span>文件上傳示例<span class="hljs-regexp"></<span class="hljs-operator">title</span>></span><span class="hljs-regexp"><<span class="hljs-operator">style</span>></span><span class="css"><span class="hljs-regexp">body</span> <span class="hljs-operator">{
<span class="hljs-operator"><span class="hljs-title1">font-family</span>:<span class="hljs-string"><span class="hljs-operator">"Microsoft Yahei"</span>,<span class="hljs-operator">"Helvetica Neue"</span>,Helvetica,Arial,sans-serif</span></span>;
<span class="hljs-operator"><span class="hljs-title1">font-size</span>:<span class="hljs-string"><span class="hljs-number">16px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">padding</span>:<span class="hljs-string"><span class="hljs-number">5px</span></span></span>;
}</span><span class="hljs-regexp">.form</span><span class="hljs-operator">{
<span class="hljs-operator"><span class="hljs-title1">padding</span>:<span class="hljs-string"> <span class="hljs-number">15px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">font-size</span>:<span class="hljs-string"> <span class="hljs-number">16px</span></span></span>;
}</span><span class="hljs-regexp">.form</span> <span class="hljs-regexp">.text</span> <span class="hljs-operator">{
<span class="hljs-operator"><span class="hljs-title1">padding</span>:<span class="hljs-string"> <span class="hljs-number">3px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">margin</span>:<span class="hljs-string"><span class="hljs-number">2px</span> <span class="hljs-number">10px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">width</span>:<span class="hljs-string"> <span class="hljs-number">240px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">height</span>:<span class="hljs-string"> <span class="hljs-number">24px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">line-height</span>:<span class="hljs-string"> <span class="hljs-number">28px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">border</span>:<span class="hljs-string"> <span class="hljs-number">1px</span> solid <span class="hljs-title">#D4D4D4</span></span></span>;
}</span><span class="hljs-regexp">.form</span> <span class="hljs-regexp">.btn</span><span class="hljs-operator">{
<span class="hljs-operator"><span class="hljs-title1">margin</span>:<span class="hljs-string"><span class="hljs-number">6px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">padding</span>:<span class="hljs-string"> <span class="hljs-number">6px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">width</span>:<span class="hljs-string"> <span class="hljs-number">120px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">font-size</span>:<span class="hljs-string"> <span class="hljs-number">16px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">border</span>:<span class="hljs-string"> <span class="hljs-number">1px</span> solid <span class="hljs-title">#D4D4D4</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">cursor</span>:<span class="hljs-string"> pointer</span></span>;
<span class="hljs-operator"><span class="hljs-title1">background</span>:<span class="hljs-string"><span class="hljs-title">#eee</span></span></span>;
}</span><span class="hljs-regexp">.form</span> <span class="hljs-regexp">.file</span><span class="hljs-operator">{
<span class="hljs-operator"><span class="hljs-title1">margin</span>:<span class="hljs-string"><span class="hljs-number">6px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">padding</span>:<span class="hljs-string"> <span class="hljs-number">6px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">width</span>:<span class="hljs-string"> <span class="hljs-number">220px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">font-size</span>:<span class="hljs-string"> <span class="hljs-number">16px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">border</span>:<span class="hljs-string"> <span class="hljs-number">1px</span> solid <span class="hljs-title">#D4D4D4</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">cursor</span>:<span class="hljs-string"> pointer</span></span>;
<span class="hljs-operator"><span class="hljs-title1">background</span>:<span class="hljs-string"><span class="hljs-title">#eee</span></span></span>;
}</span><span class="hljs-regexp">a</span><span class="hljs-operator">{
<span class="hljs-operator"><span class="hljs-title1">color</span>:<span class="hljs-string"> <span class="hljs-title">#868686</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">cursor</span>:<span class="hljs-string"> pointer</span></span>;
}</span><span class="hljs-operator"><span class="hljs-title1">a</span>:<span class="hljs-string">hover{
text-decoration: underline</span></span>;
}
<span class="hljs-regexp">h2</span><span class="hljs-operator">{
<span class="hljs-operator"><span class="hljs-title1">color</span>:<span class="hljs-string"> <span class="hljs-title">#4288ce</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">font-weight</span>:<span class="hljs-string"> <span class="hljs-number">400</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">padding</span>:<span class="hljs-string"> <span class="hljs-number">6px</span> <span class="hljs-number">0</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">margin</span>:<span class="hljs-string"> <span class="hljs-number">6px</span> <span class="hljs-number">0</span> <span class="hljs-number">0</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">font-size</span>:<span class="hljs-string"> <span class="hljs-number">28px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">border-bottom</span>:<span class="hljs-string"> <span class="hljs-number">1px</span> solid <span class="hljs-title">#eee</span></span></span>;
}</span><span class="hljs-regexp">div</span><span class="hljs-operator">{
<span class="hljs-operator"><span class="hljs-title1">margin</span>:<span class="hljs-string"><span class="hljs-number">8px</span></span></span>;
}</span><span class="hljs-regexp">.info</span><span class="hljs-operator">{
<span class="hljs-operator"><span class="hljs-title1">padding</span>:<span class="hljs-string"> <span class="hljs-number">12px</span> <span class="hljs-number">0</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">border-bottom</span>:<span class="hljs-string"> <span class="hljs-number">1px</span> solid <span class="hljs-title">#eee</span></span></span>;
}</span><span class="hljs-regexp">.copyright</span><span class="hljs-operator">{
<span class="hljs-operator"><span class="hljs-title1">margin-top</span>:<span class="hljs-string"> <span class="hljs-number">24px</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">padding</span>:<span class="hljs-string"> <span class="hljs-number">12px</span> <span class="hljs-number">0</span></span></span>;
<span class="hljs-operator"><span class="hljs-title1">border-top</span>:<span class="hljs-string"> <span class="hljs-number">1px</span> solid <span class="hljs-title">#eee</span></span></span>;
}</span></span><span class="hljs-regexp"></<span class="hljs-operator">style</span>></span><span class="hljs-regexp"></<span class="hljs-operator">head</span>></span><span class="hljs-regexp"><<span class="hljs-operator">body</span>></span><span class="hljs-regexp"><<span class="hljs-operator">h2</span>></span>文件上傳示例<span class="hljs-regexp"></<span class="hljs-operator">h2</span>></span><span class="hljs-regexp"><<span class="hljs-operator">FORM</span> <span class="hljs-operator">method</span>=<span class="hljs-string">"post"</span> <span class="hljs-operator">enctype</span>=<span class="hljs-string">"multipart/form-data"</span> <span class="hljs-operator">class</span>=<span class="hljs-string">"form"</span> <span class="hljs-operator">action</span>=<span class="hljs-string">"{:url('up')}"</span>></span>
選擇文件:<span class="hljs-regexp"><<span class="hljs-operator">INPUT</span> <span class="hljs-operator">type</span>=<span class="hljs-string">"file"</span> <span class="hljs-operator">class</span>=<span class="hljs-string">"file"</span> <span class="hljs-operator">name</span>=<span class="hljs-string">"file"</span>></span><span class="hljs-regexp"><<span class="hljs-operator">br</span>/></span><span class="hljs-regexp"><<span class="hljs-operator">INPUT</span> <span class="hljs-operator">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-operator">class</span>=<span class="hljs-string">"btn"</span> <span class="hljs-operator">value</span>=<span class="hljs-string">" 提交 "</span>></span><span class="hljs-regexp"></<span class="hljs-operator">FORM</span>></span><span class="hljs-regexp"><<span class="hljs-operator">div</span> <span class="hljs-operator">class</span>=<span class="hljs-string">"copyright"</span>></span><span class="hljs-regexp"><<span class="hljs-operator">a</span> <span class="hljs-operator">title</span>=<span class="hljs-string">"官方網站"</span> <span class="hljs-operator">href</span>=<span class="hljs-string">"http://www.thinkphp.cn"</span>></span>ThinkPHP<span class="hljs-regexp"></<span class="hljs-operator">a</span>></span><span class="hljs-regexp"><<span class="hljs-operator">span</span>></span>V5<span class="hljs-regexp"></<span class="hljs-operator">span</span>></span><span class="hljs-regexp"><<span class="hljs-operator">span</span>></span>{ 十年磨一劍-為API開發設計的高性能框架 }<span class="hljs-regexp"></<span class="hljs-operator">span</span>></span><span class="hljs-regexp"></<span class="hljs-operator">div</span>></span><span class="hljs-regexp"></<span class="hljs-operator">body</span>></span><span class="hljs-regexp"></<span class="hljs-operator">html</span>></span>
```
```
訪問下面的URL地址:
```
<pre class="calibre18">
```
<span class="hljs-string">http:</span>
<span class="hljs-comment">//tp5.com/index/upload</span>
```
```

如果沒有選擇任何文件點擊提交的話,會顯示:

選擇文件后點擊提交:


默認的上傳文件會按照當前的日期自動保存
## 上傳文件驗證
可以在上傳之前調用`validate`方法設置驗證規則,例如:
```
<pre class="calibre18">
```
<span class="hljs-comment">// 文件上傳提交</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">up</span><span class="hljs-number">(Request <span class="hljs-regexp">$request</span>)</span></span>{
<span class="hljs-comment">// 獲取表單上傳文件</span><span class="hljs-regexp">$file</span> = <span class="hljs-regexp">$request</span>->file(<span class="hljs-string">'file'</span>);
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">empty</span>(<span class="hljs-regexp">$file</span>)) {
<span class="hljs-regexp">$this</span>->error(<span class="hljs-string">'請選擇上傳文件'</span>);
}
<span class="hljs-comment">// 移動到框架應用根目錄/public/uploads/ 目錄下</span><span class="hljs-regexp">$info</span> = <span class="hljs-regexp">$file</span>->validate([<span class="hljs-string">'ext'</span> => <span class="hljs-string">'jpg,png'</span>])->move(ROOT_PATH . <span class="hljs-string">'public'</span> . DS . <span class="hljs-string">'uploads'</span>);
<span class="hljs-keyword">if</span> (<span class="hljs-regexp">$info</span>) {
<span class="hljs-regexp">$this</span>->success(<span class="hljs-string">'文件上傳成功:'</span> . <span class="hljs-regexp">$info</span>->getRealPath());
} <span class="hljs-keyword">else</span> {
<span class="hljs-comment">// 上傳失敗獲取錯誤信息</span><span class="hljs-regexp">$this</span>->error(<span class="hljs-regexp">$file</span>->getError());
}
}
```
```
`validate`方法設置了允許上傳的文件后綴是jpg和png,當我們選擇一個gif格式的文件后,會提示:

`validate`方法支持的驗證規則包括:
驗證規則 說明 參數類型 size 上傳文件最大字節大小 integer ext 允許上傳的文件后綴 數組或者字符串 type 允許上傳的文件類型 數組或者字符串如果上傳的文件后綴是圖像格式的話,系統會自動檢測是否為合法的圖像文件,例如,我們創建一個hello.jpg文件,并且寫入下列文本內容
```
<pre class="calibre18">
```
Hello,ThinkPHP5!
```
```
當我們上傳該文件并且提交后顯示:

> 注意:文件上傳驗證用到了`exif`擴展,如果沒有開啟請自行開啟。
如果你統一使用驗證類`think\Validate`對表單進行驗證,也可以直接使用控制器類`think\Controller`的`validate`方法進行上傳文件驗證,修改控制器up方法的代碼為:
```
<pre class="calibre18">
```
<span class="hljs-comment">// 文件上傳提交</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">up</span><span class="hljs-number">(Request <span class="hljs-regexp">$request</span>)</span></span>{
<span class="hljs-comment">// 獲取表單上傳文件</span><span class="hljs-regexp">$file</span> = <span class="hljs-regexp">$request</span>->file(<span class="hljs-string">'file'</span>);
<span class="hljs-comment">// 上傳文件驗證</span><span class="hljs-regexp">$result</span> = <span class="hljs-regexp">$this</span>->validate([<span class="hljs-string">'file'</span> => <span class="hljs-regexp">$file</span>], [<span class="hljs-string">'file'</span>=><span class="hljs-string">'require|image'</span>],[<span class="hljs-string">'file.require'</span> => <span class="hljs-string">'請選擇上傳文件'</span>, <span class="hljs-string">'file.image'</span> => <span class="hljs-string">'非法圖像文件'</span>]);
<span class="hljs-keyword">if</span>(<span class="hljs-keyword">true</span> !== <span class="hljs-regexp">$result</span>){
<span class="hljs-regexp">$this</span>->error(<span class="hljs-regexp">$result</span>);
}
<span class="hljs-comment">// 移動到框架應用根目錄/public/uploads/ 目錄下</span><span class="hljs-regexp">$info</span> = <span class="hljs-regexp">$file</span>->move(ROOT_PATH . <span class="hljs-string">'public'</span> . DS . <span class="hljs-string">'uploads'</span>);
<span class="hljs-keyword">if</span> (<span class="hljs-regexp">$info</span>) {
<span class="hljs-regexp">$this</span>->success(<span class="hljs-string">'文件上傳成功:'</span> . <span class="hljs-regexp">$info</span>->getRealPath());
} <span class="hljs-keyword">else</span> {
<span class="hljs-comment">// 上傳失敗獲取錯誤信息</span><span class="hljs-regexp">$this</span>->error(<span class="hljs-regexp">$file</span>->getError());
}
}
```
```
關鍵的代碼是這行:
```
<pre class="calibre18">
```
<span class="hljs-comment">// 上傳文件驗證</span><span class="hljs-regexp">$result</span> = <span class="hljs-regexp">$this</span>->validate([<span class="hljs-string">'file'</span> => <span class="hljs-regexp">$file</span>], [<span class="hljs-string">'file'</span>=><span class="hljs-string">'require|image'</span>],[<span class="hljs-string">'file.require'</span> => <span class="hljs-string">'請選擇上傳文件'</span>, <span class="hljs-string">'file.image'</span> => <span class="hljs-string">'非法圖像文件'</span>]);
```
```
由于設置了`require`驗證規則(表示必須上傳文件),所以如果沒有選擇任何文件直接提交的話,頁面會提示:

`image`驗證規則表示上傳的必須是一個圖像文件,如果選擇上傳了一個文本文件,頁面會提示:

如果需要上傳一個100\*100的`PNG`圖像文件,可以這樣進行驗證:
```
<pre class="calibre18">
```
<span class="hljs-comment">// 上傳文件驗證</span><span class="hljs-regexp">$result</span> = <span class="hljs-regexp">$this</span>->validate([<span class="hljs-string">'file'</span> => <span class="hljs-regexp">$file</span>], [<span class="hljs-string">'file'</span>=><span class="hljs-string">'require|image:100,100,png'</span>],[<span class="hljs-string">'file.require'</span> => <span class="hljs-string">'請選擇上傳文件'</span>, <span class="hljs-string">'file.image'</span> => <span class="hljs-string">'必須是100*100的PNG格式文件'</span>]);
```
```
更多的上傳文件驗證規則還包括:
驗證規則 說明 file 驗證是否為File對象 image 驗證是否為圖像File對象 image:width,height\[,type\] 驗證圖像文件的類型和寬高 fileExt:zip,doc,... 驗證文件后綴 fileMime:image/png,... 驗證文件類型 fileSize:1024 驗證文件大小## 文件保存規則
可以在上傳之前調用`rule`方法設置上傳文件的保存規則。
```
<pre class="calibre18">
```
<span class="hljs-comment">// 文件上傳提交</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">up</span><span class="hljs-number">(Request <span class="hljs-regexp">$request</span>)</span></span>{
<span class="hljs-comment">// 獲取表單上傳文件</span><span class="hljs-regexp">$file</span> = <span class="hljs-regexp">$request</span>->file(<span class="hljs-string">'file'</span>);
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">empty</span>(<span class="hljs-regexp">$file</span>)) {
<span class="hljs-regexp">$this</span>->error(<span class="hljs-string">'請選擇上傳文件'</span>);
}
<span class="hljs-comment">// 移動到框架應用根目錄/public/uploads/ 目錄下</span><span class="hljs-regexp">$info</span> = <span class="hljs-regexp">$file</span>->rule(<span class="hljs-string">'md5'</span>)->move(ROOT_PATH . <span class="hljs-string">'public'</span> . DS . <span class="hljs-string">'uploads'</span>);
<span class="hljs-keyword">if</span> (<span class="hljs-regexp">$info</span>) {
<span class="hljs-regexp">$this</span>->success(<span class="hljs-string">'文件上傳成功:'</span> . <span class="hljs-regexp">$info</span>->getRealPath());
} <span class="hljs-keyword">else</span> {
<span class="hljs-comment">// 上傳失敗獲取錯誤信息</span><span class="hljs-regexp">$this</span>->error(<span class="hljs-regexp">$file</span>->getError());
}
}
```
```

系統默認提供了幾種上傳命名規則,包括:
規則 描述 date 根據日期和微秒數生成(默認規則) md5 對文件使用md5\_file散列生成 sha1 對文件使用sha1\_file散列生成> 其中md5和sha1規則會自動以散列值的前兩個字符作為子目錄,后面的散列值作為文件名。
如果需要自定義上傳文件的保存規則,可以使用:
```
<pre class="calibre18">
```
/<span class="hljs-regexp">/ 移動到框架應用根目錄/public</span><span class="hljs-regexp">/uploads/</span> 目錄下
<span class="hljs-regexp">$info</span> = <span class="hljs-regexp">$file</span>->rule(<span class="hljs-string">'uniqid'</span>)->move(<span class="hljs-number">ROOT_PATH </span>. <span class="hljs-string">'public'</span> . <span class="hljs-number">DS </span>. <span class="hljs-string">'uploads'</span>);
```
```
這里使用了`uniqid`函數來生成唯一的ID命名上傳文件,如果必要,還可以支持使用閉包定義規則,例如:
```
<pre class="calibre18">
```
<span class="hljs-comment">// 移動到框架應用根目錄/public/uploads/ 目錄下</span><span class="hljs-regexp">$info</span> = <span class="hljs-regexp">$file</span>->rule(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-number">(<span class="hljs-regexp">$file</span>)</span> </span>{
<span class="hljs-comment">// 使用自定義的文件保存規則</span><span class="hljs-keyword">return</span> <span class="hljs-regexp">$file</span>->getInfo(<span class="hljs-string">'type'</span>) . uniqid();
})->move(ROOT_PATH . <span class="hljs-string">'public'</span> . DS . <span class="hljs-string">'uploads'</span>);
```
```

如果希望指定某個文件的保存文件名,還可以直接使用:
```
<pre class="calibre18">
```
/<span class="hljs-regexp">/ 移動到框架應用根目錄/public</span><span class="hljs-regexp">/uploads/</span> 目錄下
<span class="hljs-regexp">$info</span> = <span class="hljs-regexp">$file</span>->move(<span class="hljs-number">ROOT_PATH </span>. <span class="hljs-string">'public'</span> . <span class="hljs-number">DS </span>. <span class="hljs-string">'uploads'</span>,<span class="hljs-string">'test'</span>);
```
```

如果希望保持上傳文件的原文件名保存,則可以使用
```
<pre class="calibre18">
```
/<span class="hljs-regexp">/ 移動到框架應用根目錄/public</span><span class="hljs-regexp">/uploads/</span> 目錄下
<span class="hljs-regexp">$info</span> = <span class="hljs-regexp">$file</span>->move(<span class="hljs-number">ROOT_PATH </span>. <span class="hljs-string">'public'</span> . <span class="hljs-number">DS </span>. <span class="hljs-string">'uploads'</span>,<span class="hljs-string">''</span>);
```
```
默認情況下,會覆蓋服務器上傳目錄下的同名文件,如果不希望覆蓋,可以使用:
```
<pre class="calibre18">
```
<span class="hljs-comment">// 移動到服務器的上傳目錄 并且設置不覆蓋</span><span class="hljs-regexp">$file</span>->move(ROOT_PATH . <span class="hljs-string">'public'</span> . DS . <span class="hljs-string">'uploads'</span>,<span class="hljs-keyword">true</span>,<span class="hljs-keyword">false</span>);
```
```
如果要獲取上傳的保存文件名,可以調用返回對象的`getSaveName`方法:
```
<pre class="calibre18">
```
<span class="hljs-regexp">$info</span> = <span class="hljs-regexp">$file</span>->rule(<span class="hljs-string">'md5'</span>)->move(ROOT_PATH . <span class="hljs-string">'public'</span> . DS . <span class="hljs-string">'uploads'</span>);
<span class="hljs-keyword">if</span> (<span class="hljs-regexp">$info</span>) {
<span class="hljs-keyword">echo</span> <span class="hljs-regexp">$info</span>->getSaveName();
} <span class="hljs-keyword">else</span> {
<span class="hljs-regexp">$this</span>->error(<span class="hljs-regexp">$file</span>->getError());
}
```
```
## 多文件上傳
如果你使用的是多文件上傳表單,例如:
```
<pre class="calibre18">
```
<<span class="hljs-operator">FORM</span> method=<span class="hljs-string">"post"</span> enctype=<span class="hljs-string">"multipart/form-data"</span> <span class="hljs-operator"><span class="hljs-keyword">class</span>=</span><span class="hljs-string">"form"</span> action=<span class="hljs-string">"{:url('up')}"</span>>
<input <span class="hljs-operator"><span class="hljs-keyword">type</span>=</span><span class="hljs-string">"file"</span> name=<span class="hljs-string">"image[]"</span> /> <br>
<input <span class="hljs-operator"><span class="hljs-keyword">type</span>=</span><span class="hljs-string">"file"</span> name=<span class="hljs-string">"image[]"</span> /> <br>
<input <span class="hljs-operator"><span class="hljs-keyword">type</span>=</span><span class="hljs-string">"file"</span> name=<span class="hljs-string">"image[]"</span> /> <br>
<<span class="hljs-operator">INPUT</span> <span class="hljs-operator"><span class="hljs-keyword">type</span>=</span><span class="hljs-string">"submit"</span> <span class="hljs-operator"><span class="hljs-keyword">class</span>=</span><span class="hljs-string">"btn"</span> value=<span class="hljs-string">" 提交 "</span>>
</<span class="hljs-operator">FORM</span>>
```
```
控制器代碼可以改成:
```
<pre class="calibre18">
```
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">up</span><span class="hljs-number">(Request <span class="hljs-regexp">$request</span>)</span></span>{
<span class="hljs-comment">// 獲取表單上傳文件</span><span class="hljs-regexp">$files</span> = <span class="hljs-regexp">$request</span>->file(<span class="hljs-string">'image'</span>);
<span class="hljs-regexp">$item</span> = [];
<span class="hljs-keyword">foreach</span>(<span class="hljs-regexp">$files</span> <span class="hljs-keyword">as</span> <span class="hljs-regexp">$file</span>){
<span class="hljs-comment">// 移動到框架應用根目錄/public/uploads/ 目錄下</span><span class="hljs-regexp">$info</span> = <span class="hljs-regexp">$file</span>->move(ROOT_PATH . <span class="hljs-string">'public'</span> . DS . <span class="hljs-string">'uploads'</span>);
<span class="hljs-keyword">if</span>(<span class="hljs-regexp">$info</span>){
<span class="hljs-regexp">$item</span>[] = <span class="hljs-regexp">$info</span>->getRealPath();
}<span class="hljs-keyword">else</span>{
<span class="hljs-comment">// 上傳失敗獲取錯誤信息</span><span class="hljs-regexp">$this</span>->error(<span class="hljs-regexp">$file</span>->getError());
}
}
<span class="hljs-regexp">$this</span>->success(<span class="hljs-string">'文件上傳成功'</span>.implode(<span class="hljs-string">'<br/>'</span>,<span class="hljs-regexp">$item</span>));
}
```
```
## 后續文件操作
上傳成功后返回的是`File`對象,除了可以使用`SplFileObject`的屬性和方法之外,還可以使用File類自身提供的下列方法,便于進行后續的文件處理(例如對圖像文件進行剪裁處理或者移動到遠程服務器)。
方法 描述 getSaveName 獲取保存的文件名(包含動態生成的目錄) getInfo 獲取上傳文件信息 getMime 獲取文件的MIME信息 md5 獲取文件的md5散列值 sha1 獲取文件的sha1散列值下面是一個簡單的FTP文件移動的處理例子。
```
<pre class="calibre18">
```
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">up</span><span class="hljs-number">(Request <span class="hljs-regexp">$request</span>)</span></span>{
<span class="hljs-comment">// 獲取表單上傳文件</span><span class="hljs-regexp">$file</span> = <span class="hljs-regexp">$request</span>->file(<span class="hljs-string">'file'</span>);
<span class="hljs-comment">// 上傳文件</span><span class="hljs-regexp">$info</span> = <span class="hljs-regexp">$file</span>->move(ROOT_PATH . <span class="hljs-string">'public'</span> . DS . <span class="hljs-string">'uploads'</span>);
<span class="hljs-keyword">if</span> (<span class="hljs-regexp">$info</span>) {
<span class="hljs-comment">// 移動文件到FTP服務器</span><span class="hljs-regexp">$link</span> = ftp_connect(<span class="hljs-string">'212.45.5.78'</span>);
ftp_login(<span class="hljs-regexp">$link</span>, <span class="hljs-string">'root'</span>, <span class="hljs-string">'password'</span>);
<span class="hljs-comment">/* 移動文件 */</span><span class="hljs-regexp">$path</span> = ftp_pwd(<span class="hljs-regexp">$link</span>) . <span class="hljs-string">'/uploads/'</span>;
<span class="hljs-keyword">if</span> (!ftp_put(<span class="hljs-regexp">$link</span>, <span class="hljs-regexp">$path</span>.<span class="hljs-regexp">$info</span>->getFilename(), <span class="hljs-regexp">$info</span>->getRealPath(), FTP_BINARY)) {
<span class="hljs-regexp">$this</span>->error(<span class="hljs-string">'文件上傳保存錯誤!'</span>);
}
} <span class="hljs-keyword">else</span> {
<span class="hljs-comment">// 上傳失敗獲取錯誤信息</span><span class="hljs-regexp">$this</span>->error(<span class="hljs-regexp">$file</span>->getError());
}
}
```
```
還可以對上傳的文件進行處理,后面我們還會講到對上傳圖像文件進行額外的圖像處理。
- 脕茫隆壟脨貌脩脭
- 脕茫隆壟脨貌脩脭
- 脪祿隆壟祿霉麓隆
- 脪祿隆壟祿霉麓隆
- 露鎂隆壟URL潞脥脗路脫脡
- 露鎂隆壟URL潞脥脗路脫脡
- 脠媒隆壟脟毛脟貿潞脥脧矛脫婁
- 脠媒隆壟脟毛脟貿潞脥脧矛脫婁
- 脣脛隆壟脢媒戮脻驢芒
- 脣脛隆壟脢媒戮脻驢芒
- 脦氓隆壟虜茅脩爐脫茂脩脭
- 脦氓隆壟虜茅脩爐脫茂脩脭
- 脕霉隆壟脛攏脨脥潞脥鹿脴脕陋
- 攏簍1攏漏脛攏脨脥露簍脪氓
- 攏簍2攏漏祿霉麓隆虜脵脳梅
- 攏簍3攏漏露脕脠隆脝梅潞脥脨脼賂脛脝梅
- 攏簍4攏漏脌脿脨脥脳陋祿祿潞脥脳脭露爐脥錨魯脡
- 攏簍5攏漏虜茅脩爐路露脦摟
- 攏簍6攏漏脢盲脠毛潞脥脩茅脰隴
- 攏簍7攏漏鹿脴脕陋
- 攏簍8攏漏脛攏脨脥脢盲魯枚
- 脝脽隆壟脢脫脥錄潞脥脛攏擄氓
- 脝脽隆壟脢脫脥錄潞脥脛攏擄氓
- 擄脣隆壟碌梅脢脭潞脥脠脮脰戮
- 擄脣隆壟碌梅脢脭潞脥脠脮脰戮
- 戮脜隆壟API驢陋路壟
- 戮脜隆壟API驢陋路壟
- 脢廬隆壟脙眉脕卯脨脨鹿隴戮脽
- 脢廬隆壟脙眉脕卯脨脨鹿隴戮脽
- 脢廬脪祿隆壟脌漏脮鹿
- 脢廬脪祿隆壟脌漏脮鹿
- 脢廬露鎂隆壟脭脫脧卯
- Cookie
- Session
- 碌樓脭陋虜芒脢脭
- 脥錄脧帽麓婁脌鉚
- 脦脛錄鎂脡脧麓蘆
- 脩茅脰隴脗毛
- 賂陸脗錄
- A隆壟魯攏錄沒脦脢脤芒錄爐
- B隆壟3.2潞脥5.0脟酶鹵冒
- C隆壟脰煤脢脰潞爐脢媒
- 路盧脥芒脝陋攏潞脩摟脧擄ThinkPHP5碌脛脮媒脠路脳脣脢脝
- 路盧脥芒脝陋攏潞脩摟脧擄ThinkPHP5碌脛脮媒脠路脳脣脢脝