使用Zend框架實現(xiàn)PHP文件上傳
Zend Framework是流行的PHP開發(fā)框架,使用Zend框架,能夠方便快捷的實現(xiàn)各項常用功能。這里向你介紹使用Zend框架來創(chuàng)建文件上傳功能,該機制能夠輕而易舉地接收、確認和處理要上傳的文件。
一、簡介
無論是管理YouTube上的視頻、在SlideShare上共享PowerPoint演示文稿,還是使用開源電子商務平臺Magento更新在線商店中的商品圖像,我們都有用到基于web的文件上傳功能。但是,這個功能到底是如何工作的呢?文件是如何從本地機器傳送到遠程服務器的?本文將向讀者詳細介紹如何使用流行的Zend框架來創(chuàng)建我們自己的PHP文件上傳機制,該機制能夠輕而易舉地接收、確認和處理要上傳的文件。
二、配置處理文件上載的PHP
PHP本身能夠通過Web表單來完成文件上載,不過無論使用標準PHP代碼還是使用Zend框架來管理文件上傳,都有必要花一些時間來檢測直接影響PHP的有關功能的配置偽指令,這些指令包括:
◆file_uploads:這個偽指令啟用PHP的文件上載功能。在默認情形下,這個偽指令會被啟用。
◆upload_max_filesize:這個偽指令定義了要上載的文件的最大尺寸。在默認情形下,這個偽指令被設置為2M。
◆upload_tmp_dir:這個偽指令定義了PHP臨時存儲要上傳的文件的目錄,文件在傳入最終目的地之前將臨時存放于此,該目錄是由開發(fā)人員指定的。在默認情形下,這個偽指令不會賦值,這意味著PHP將使用系統(tǒng)的默認值,舉例來說,許多l(xiāng)inux發(fā)行版中的臨時目錄為/tmp。
◆post_max_size:設定POST 數(shù)據(jù)所允許的最大大小。php默認的post_max_size 為2M。
◆max_execution_time:雖然與文件上載的關系不是非常密切,但是這個偽指令在PHP的文件上載功能中卻扮演了一個重要角色,因為它定義了PHP腳本的執(zhí)行時間。對于尺寸特別大的文件來說,可能需要很長的時間才能傳輸?shù)轿募掌鳎钥梢钥紤]將這個偽指令的默認值即30秒改為60乃至90秒。
三、創(chuàng)建文件上載表單
下面我們將創(chuàng)建一個Web表單示例,它能夠用來瀏覽本地計算機的文件系統(tǒng)以及確定要上傳的文件。我們將盡力使該示例保持簡單,創(chuàng)建的文件上載表單的外觀如圖1所示。
這個表單的創(chuàng)建方式跟我們之前創(chuàng)建的其他表單大同小異,只是有一些輕微的區(qū)別。用于創(chuàng)建這個表單的HTML代碼如清單1所示。按照Zend框架的慣例,我們將這個表單放入名為upload.phtml的視圖中,它是名為admin的控制器中動作upload的一部分。
- <form enctype="multipart/form-data" method="post" action="/admin/upload">
- <p>
- What file would you like to upload?<br />
- <input type="file" name="video-upload" size="40" />
- < SPAN>p>
- <p>
- <input type="submit" name="submit" class="submit" value="Upload Video" />
- < SPAN>p>
- < SPAN>form>
在這個表單中,有兩處代碼需要格外注意:
enctype="multipart/form-data":當我們使用Web表單發(fā)送大量的二進制數(shù)據(jù)的時候,就應該使用這個表單屬性。因為諸如電子表格以及視頻等文件中含有大量的二進制數(shù)據(jù),所以創(chuàng)建文件上載表單時應該包含這個屬性。
- <input type="file" name="video-upload" size="40" />
#T#上面這個表單元素會創(chuàng)建允許用戶在本地文件系統(tǒng)搜索要上傳的文件的表單機制。當提交按鈕被按下的時候,這個文件將被上傳,并將其發(fā)送給表單動作所標識的腳本(本例中,為upload.php)做進一步的處理。
如上所述,文件將被上傳給表單的動作屬性所標識的腳本。然而,除非該腳本對該文件做實際的處理,否則數(shù)據(jù)會被丟失。在下一節(jié)中,我們將介紹如何使用Zend框架的Zend_File_Transfer組件來處理上傳的文件。#p#
四、關于Zend_File_Transfer組件
如同Zend框架的其他強大組件旨在簡化我們的開發(fā)任務那樣,Zend_File_Transfer組件旨在簡化從用戶的計算機向web服務器上傳文件的工作。實際上,這個組件在處理文件上傳方面非常靈活,它可以使用諸如FTP和WebDAV協(xié)議來傳送文件,不過我們這里只討論它的最初設計意圖。讓我們首先創(chuàng)建最簡單上載動作處理,不過它仍能接收和處理一個上載的文件,如下所示:
- public function uploadAction()
- {
- if ($this->getRequest()->isPost()) {
- $upload = new Zend_File_Transfer_Adapter_Http();
- $upload->setDestination($this->config->uploads->product->supplements);
- if ($upload->receive()) {
- echo "The file has been uploaded!";
- }
- }
- }
為了在下面的描述中輕松引用代碼,我們這里為動作代碼添加了相應的行號。
04行的代碼確定POST請求是否已經(jīng)提交給了該動作。這對于創(chuàng)建為用戶呈現(xiàn)表單以及通過表單提交數(shù)據(jù)的動作來說都非常有用。
06行的代碼調用Zend_File_Transfer類組件,并使用了能夠處理通過Web表單提交的數(shù)據(jù)的HTTP適配器。
08行的代碼用于設置文件上傳的最終目的地。雖然可以直接向該方法傳遞一個路徑,不過我發(fā)現(xiàn)將路徑存放到application.ini文件中然后根據(jù)需要檢索配置參數(shù)會更加方便一些。 這允許我們依照要求輕松更改目的地路徑,當我們的代碼從開發(fā)工作站遷移到生產服務器時這一點格外有用。
10行的代碼負責接收文件,并將其移動到要求的目的地。
或許您覺得這難以置信,但是這短短的十六行代碼的確能夠接收并將上傳來的文件移動到服務器的預定位置! 然而,現(xiàn)在還不要高興得太早,因為該腳本缺少接收用戶輸入時應具備的一個關鍵步驟,因為這個腳本允許用戶上傳任意文件,這是萬萬不可的! 幸運的是,Zend_File_Transfer組件帶有檢查文件上傳處理方面能夠想到的所有方面的數(shù)據(jù)驗證方法。
五、對上載的文件進行檢驗
我們至少希望檢查被上傳文件的一個或者幾個關鍵特性,如文件的大小,或者MIME類型等。實際上,有多種方法可以用來檢索這些特性。舉例來說,為了檢索文件的MIME類型,我們可在接收文件之后調用getMimeType()方法,具體代碼如下所示:
- if ($upload->receive()) {
- echo "The file type is {$upload->getMimeType()}";
- }
如果我們向服務器上傳了一個PDF文件,并調用了getMimeType方法,那么將會返回application/x-pdf。當用戶只應上傳特定類型的文件時,這個方法非常有用。下面是一個例子:
- if ($upload->getMimeType() == "application/x-pdf") {
- $upload->receive();
- echo "File received";
- } else {
- echo "Please upload a PDF";
- }
當然,檢查文件大小或者類型只是證實過程的一小部分而已。為了簡化驗證工作,您可能希望在接收被上傳的文件之前來進行這些工作,實際上Zend_File_Transfer組件已經(jīng)為我們提供了18個驗證方法。Zend框架文檔提供了這些驗證函數(shù)的完整說明。我們可能用到的驗證函數(shù)之一便是ImageSize,它能檢查一個被上載圖像的大小,以便確保其大小介于給定的最大和最小尺寸之間。在某些情況下,這可能非常有用,例如在需要保持縮略圖尺寸保持一致的時候。下面的例子將確保所有上傳的圖像都為PNG類型,同時其大小符合160×160像素的要求:
- if ($this->getRequest()->isPost()) {
- $upload = new Zend_File_Transfer_Adapter_Http();
- $upload->setDestination($this->config->uploads->product->supplements);
- $upload->addValidator('MimeType', false, 'image/png');
- $upload->addValidator('ImageSize', false,
- array('minwidth' => 160,
- 'maxwidth' => 160,
- 'minheight' => 160,
- 'maxheight' => 160)
- );
- if ($upload->isValid()) {
- $upload->receive();
- echo "File received";
- } else {
- echo "Please upload a file of type PNG and dimensions 160x160 pixels.";
- }
- }
六、進一步閱讀
如今,用戶驅動的內容已經(jīng)成為Web的關鍵組成部分,所以項目的成功可能會取決于數(shù)據(jù)從用戶到web服務器的傳送效率。在為用戶提供數(shù)據(jù)上傳功能的時候,Zend框架的Zend_File_Transfer組件可以極大的降低開發(fā)工作的復雜性!
如果您想進一步了解Zend_File_Transfer組件,請參考Zend框架的Zend_File組件文檔;另外,PHP手冊的文檔也有文件上載方面的介紹;此外,Zend_ProgressBar組件的進一步信息請參考Zend框架的Zend_ProgressBar文檔。