文件限制大小了有木有?誠然,這些都是上傳文件失敗的幾種常見原因,但這些代表了上傳問題的根源嗎,事實告訴我們,上傳錯誤可以是多種多樣,花樣百出的。
下面我就詳細説説上傳文件的過程。
【上傳文件是怎樣煉成的?】
大家都知道上傳文件,但文件是怎麼上傳的呢?
我們來看一段簡單的代碼:
假設我們使用 PHP 作為服務器端的腳本語言。
- <form enctype="multipart/form-data" action="upload.php" method="post">
- <input name="userfile" type="file">
- <input type="submit" value="上傳文件">
- </form>
這是上傳文件的一個簡單 HTML 代碼例子
我們指定了 form 標籤的 enctype 屬性為 multipart/form-data,代表了不對錶單內字符進行編碼,一般在使用包含文件上傳控件的表單中使用。
當我們點擊按鈕提交表單後,瀏覽器會將請求提交的服務器,服務器保存文件,看似文件上傳已經成功,然而這才是文件上傳的開始而已呀。
這時候 upload.php 開始執行,與常用的 GETPOST 的請求不同,文件上傳到服務器後,並沒有直接保存到我們需要保存的目錄,而是暫存在一個臨時文件目錄下。
upload.php 需要做的就是把這個文件放到我們真正需要存放的目錄中。
上傳文件的信息會作為一個全局變量保存在 $_FILES 數組中。
剛才例子中的文件的信息將會保存在 $_FILES[『userfile』] 中 (因為我們表單中上傳的字段命名為 userfile)
$_FILES['userfile']['name'] 客户端機器文件的原名稱。
$_FILES['userfile']['type'] 文件的 MIME 類型,需要瀏覽器提供該信息的支持,例如 「image/gif」 。
$_FILES['userfile']['size'] 已上傳文件的大小,單位為字節。
$_FILES['userfile']['tmp_name'] 文件被上傳後在服務端儲存的臨時文件名。 (這個很重要,不然就找不到文件了啊)
$_FILES['userfile']['error'] 和該文件上傳相關的錯誤代碼。 (如果有錯誤,那麼之前的幾個變量都會是空值,錯誤將在後面詳述)
然後程序根據這些信息,將文件保存到相應的目錄下,過程比較簡單,代碼就不做詳細列出了。
【上傳失敗是怎樣煉成的?】
如果上文中的過程順利,沒有錯誤,那麼我們上傳工作就完成啦。但老天總不會讓事情發展的如此順利,於是各種的上傳失敗出現了。
我們以論壇上傳附件為例,分析下上傳的錯誤可能都有哪些。
我把錯誤歸納為三類:
第一類,程序限制。
故名思議,就是 Discuz! 的上傳限制機制限制了,其實 Discuz! 已經給出各個上傳失敗的提示了,只是如果使用批量上傳是無法看到所有提示的嗯,所以我們用單個文件上傳來測試。
下面列出上傳限制的一些條件,並會給出一些設置的建議 (這些限制會在上傳失敗時提示):
- 1. 不支持此類擴展名
在用户組--編輯--附件相關--允許附件類型、版塊--帖子選項--附件類型中可以設定支持上傳的附件類型。
同時,注意下全局--附件類型尺寸--對應的附件類型允許的大小。
- 2. 服務器限制無法上傳那麼大的附件
這個是由於服務器限制了文件大小導致的 (後面會講到),還有,上傳 0kb 的文件也會提示這個嗯
- 3. 用户組限制無法上傳那麼大的附件
用户組--編輯--附件相關--論壇最大附件尺寸,設置大一些的值,或者設置為 0 不限制。
- 4. 文件類型限制無法上傳那麼大的附件
全局--附件類型尺寸--對應的附件類型允許的大小。
- 5. 今日你已無法上傳更多的附件
用户組--編輯--附件相關--每天最大附件數量,設置大一些的值,或者設置為 0 不限制。
- 6. 今日你已無法上傳那麼大的附件
用户組--編輯--附件相關--每天最大附件總尺寸,設置大一些的值,或者設置為 0 不限制。
- 7. 非法操作
表單 hash 值出錯,刷新頁面再提交,如果還是失敗則還原模板,更新緩存。
- 8. 沒有合法的文件被上傳
上傳文件屬於非法文件,選擇正常的文件重新發送。
- 9. 請選擇圖片文件
選擇上傳圖片時,選擇圖片類型的文件,而不是其他類型的。
第二類,服務器限制。
當上傳文件後提示:
- 1. 服務器限制無法上傳那麼大的附件
檢查下 PHP 的相關設置。 php.ini 中的 upload_max_filesize,post_max_size 兩個變量的值是否小於上傳文件的大小。
- 2. 附件文件無法保存
Discuz! data 目錄是否具有讀寫權限,建議設置 data 目錄包括其子目錄權限為 777
第三類,其他錯誤。
除了以上的常規錯誤之外,還有一些其他疑難症狀出現,在此做一個收集和彙總:
特例一:
出現狀況:
1. 服務器環境:iis+php,小文件上傳成功,大文件上傳失敗,表現為有上傳進度,而到最後提示上傳失敗。
排查情況:
1.Discuz! 程序無修改,正常。
2. 後台上傳限制關閉,正常。
3. 服務器目錄權限正確,正常。
4. 服務器上傳大小限制變量設置正確,正常。
5. 上傳文件本身沒有問題,正常。
按理來説,一切配置都沒有問題,為什麼上傳還是提示失敗呢?
原因分析:
為了驗證原因,我們跟隨程序排查,發現並沒有進入 php 程序的上傳流程,而是在上傳到服務器臨時目錄的過程中返回了一個錯誤:
- The FastCGI process exceeded configured
原來是 FastCGI 進程超時了
解決方法:
找到 FastCgi 的配置文件 「fcgiext.ini」,位於目錄 「C:WINDOWSsystem32inetsrv」 下。
在 「fcgiext.ini」 最末 php 的配置內容下增加一些參數 (如原先就有參數,則對原有參數做修改),修改如下:
- [Types]
- php=PHP
- [PHP]
- InstanceMaxRequests=10000
- EnvironmentVars=PHP_FCGI_MAX_REQUESTS:10000
- RequestTimeout=500
- ActivityTimeout=900
以上是文件上傳可能失敗的原因和解決方法,可能有疏漏,望有識之士指出~