PHP 日本研討會 2024

常見的陷阱

MAX_FILE_SIZE 項目無法指定大於 php.ini 檔案中 upload_max_filesize 設定的檔案大小。預設值為 2 MB。

如果啟用了記憶體限制,可能需要更大的 memory_limit。請確保您將 memory_limit 設定得足夠大。

如果 max_execution_time 設定得太小,腳本執行時間可能會超過該值。請確保您將 max_execution_time 設定得足夠大。

注意 max_execution_time 只會影響腳本本身的執行時間。任何花費在腳本執行之外的活動,例如使用 system() 的系統呼叫、sleep() 函式、資料庫查詢、檔案上傳過程所花費的時間等,都不會納入判斷腳本已執行的最大時間。

警告

max_input_time 設定腳本允許接收輸入的最大時間(以秒為單位),這包括檔案上傳。對於大型或多個檔案,或連線速度較慢的使用者,預設的 60 秒可能會超過。

如果 post_max_size 設定得太小,則無法上傳大型檔案。請確保您將 post_max_size 設定得足夠大。

max_file_uploads 設定控制單個請求中可以上傳的最大檔案數。如果上傳的檔案超過限制,則 $_FILES 將在達到限制後停止處理檔案。例如,如果 max_file_uploads 設定為 10,則 $_FILES 將永遠不會包含超過 10 個項目。

不驗證您操作的檔案可能會導致使用者存取其他目錄中的敏感資訊。

由於目錄清單樣式眾多,我們無法保證正確處理具有特殊名稱(例如包含空格)的檔案。

開發人員不得在同一個表單變數中混合使用一般的 input 欄位和檔案上傳欄位(透過使用像 foo[] 這樣的 input 名稱)。

新增註解

使用者貢獻的註解 10 則註解

15
amalcon _a_t_ eudoramail _d_o_t_ com
20 年前
請注意,當您想要上傳非常大的檔案(或為了測試目的而將限制設定得非常高)時,所有上傳檔案大小的限制都儲存在帶符號的 32 位元整數中。這意味著將限制設定高於約 2.1 GB 將導致 PHP 看到一個大的負數。我沒有找到任何解決這個問題的方法。
7
Nirmal Natarajan
14 年前
如果使用 IIS 7.0 或更高版本,則預設啟用請求篩選,並且允許的最大內容長度設定為 30 MB。

如果要允許上傳超過 30 MB 的檔案,則必須更改此值。

範例 web.config 項目

<configuration>
</system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="314572800"/>
</requestFiltering>
</security>
</system.webServer>
</configuration>

上面的設定將允許發送 300 MB 的資料作為請求。希望這對某些人有幫助。
4
adrien.nizon+phpnet at gmail dot com
8 年前
[編輯註解:更精確地說,在 PHP 7.1 之前,MAX_FILE_SIZE 不能超過 PHP_INT_MAX。]

請注意,MAX_FILE_SIZE 欄位不能超過 2147483647。任何更大的值都會導致上傳錯誤,該錯誤將在上傳結束時顯示

這由相關的 C 程式碼解釋
if (!strcasecmp(param, "MAX_FILE_SIZE")) {
max_file_size = atol(value);
}

字串會轉換為長整數,其最大值為... 2147483647

自 php-7.1.0beta3 以來似乎已修正 (https://github.com/php/php-src/commit/cb4c195f0b85ca5d91fee1ebe90105b8bb68356c)
4
admin at creationfarm dot com
21 年前
麥金塔 OS(不確定 OSx)使用雙分叉檔案系統,這與世界其他地區不同 ;-)。每個麥金塔檔案都有一個資料分叉和一個資源分叉。當一個雙分叉檔案碰到一個單分叉檔案系統時,必須捨棄一些東西,那就是資源分叉。這被認為是一個問題(一開始就是一個糟糕的想法),而蘋果開始建議開發人員避免將重要的檔案資訊放在檔案的資源分叉部分,但某些檔案仍然對此非常敏感。要注意的主要檔案是麥金塔字型檔案和可執行檔案,一旦麥金塔字型或可執行檔案的資源分叉消失,它就沒有用了。為了保護檔案,它們應該在上傳之前進行封裝或壓縮,以保護資源分叉。

大多數麥金塔 ftp 用戶端(例如 fetch)允許以 Macbinhex 格式上傳檔案,這也將在透過 ftp 傳輸檔案時保護資源分叉。我沒有在任何麥金塔瀏覽器中看到這種等效的格式(但我也沒有做太多的挖掘)。

僅供參考,蘋果有一個舊的實用程式名為 ResEdit,可讓您操作檔案的資源分叉部分。
1
dg at artegic dot de
14 年前
如果 UPLOAD_ERR_PARTIAL 錯誤不確定地發生:HTTPD(例如 Apache)應以 'Accept-Ranges: none' 標頭欄位回應。
1
morganaj at coleggwent dot ac dot uk
21 年前
這是另一個可能導致您的上傳失敗的原因。如果您使用 Squid 或類似的代理伺服器,請確保這不會限制 HTTP 標頭的大小。我花了幾個星期才弄清楚!
1
anders jenbo pc dk
17 年前
回應 admin at creationfarm dot com,在 NTFS 磁碟上執行的 Mac OS X 和 Windows 也使用多串流檔案系統。仍然只有資料串流在 http 上傳中傳輸。最好將 Mac OS X 檔案封裝在 .dmg 檔案中,而不是 zip,但一般使用者會發現 zip 更容易,並且它們在更多平台上受支援。
1
bohwaz
2 年前
請注意,為完整伺服器或完整虛擬主機設定較大的 post_max_size 或 upload_max_filesize 不是一個好主意,因為這可能會導致安全風險增加。

風險在於攻擊者可能會發送非常大的 POST 請求,並使您的伺服器記憶體和 CPU 過載,因為它必須先解析和處理這些請求,然後才能將它們處理到您的 PHP 腳本中。

因此,最好將此設定的變更限制為某些檔案或目錄。例如,如果我想要 /admin/files/ 和 /admin/images/,我可以使用

<If "%{REQUEST_URI} =~ m!^/admin/(files|images)/! && -n %{HTTP_COOKIE}">
php_value post_max_size 256M
php_value upload_max_filesize 256M
</If>

我也要求請求具有 cookie,以避免基本攻擊。這不會保護您免受來自未驗證使用者的攻擊,但可能會延遲任何攻擊。

此設定可以用於 Apache 伺服器設定檔和 .htaccess 檔案中。
0
tjaart at siam-data-services dot com
19 年前
我花了一段時間才弄清楚這個問題...

我認為這實際上是一個標頭問題,但它只
在進行檔案上傳時發生。

如果您在
處理來自執行檔案上傳的表單的 $_POST[''] 之後,嘗試標頭("location:http://...) 重定向
(即具有 enctype="multipart/form-data"),則重定向
如果在 `location:` 和網址之間沒有空格,在 IE 瀏覽器中會失效。
位置:& http,例如
header("location:http://...) 對比
header("location: http://...")

===================================
<?php
if ($_POST['submit']=='Upload') {
// 處理檔案並重新導向...
header("location: http://"..."/somewhere.php");
exit;
}
?>
<html><head></head><body>
<form enctype="multipart/form-data" action="upload.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="20000">
你的檔案: <input name="filename" type="file">
<input name="submit" type="submit" value="上傳">
</form>
</body></html>
===================================

只有在以下條件皆成立時才會發生此問題:
header("location:http://...) 沒有空格。
正在處理的表單有 enctype="multipart/form-data"。
瀏覽器為 IE。

要解決這個問題,只需加上空格即可。

希望這對其他人有幫助。
0
tomcashman at unitekgroup dot com
21 年前
對於 Apache,也請檢查 LimitRequestBody 指令。
如果您的環境是 Red Hat 安裝,則此設定可能會在 /etc/httpd/conf.d/php.conf 中。
預設情況下,我的設定是 512 KB。
To Top