我有一個PHP腳本,我可以透過它上傳文件,並嘗試將其從/tmp移動到test/(相對路徑,位於我的專案資料夾中,例如/var/www/html/myproject/test將是絕對路徑)。當這種情況發生時,我會收到以下錯誤。
move_uploaded_file(test/test.csv):無法開啟串流:權限被拒絕,位於/var/www/html/myproject/import.php的第X行,引用者:http://192.168.1.1/myproject /import2.php
此腳本由apache使用者執行,該使用者擁有/test的所有權(apache擁有者和apache群組都擁有此目錄),具有rwx權限。
我已經檢查了以下內容:
- safe_mode被禁用。
- open_basedir未設定。
- file_uploads已啟用。
- upload_max_filesize為2MB,檔案大小為~50KB。
- post_max_size為8MB,我的POST請求與此不接近。
- 使用絕對路徑而不是相對路徑。
- is_dir("test/")傳回true。
- is_writable("test/")回傳false。
- 在php腳本中:列印檔案擁有者(要移動的檔案)、資料夾擁有者(test/)、檔案權限和資料夾權限。檔案/資料夾擁有者顯示為apache。檔案權限為600,因此擁有者可以讀取和寫入。資料夾權限為755,因此擁有者可以讀取、寫入和執行。
- ps -aux | grep apache。將apache錯誤日誌中的PID與正在運行的進程匹配,該進程由apache用戶擁有。因此,這確認了該進程在apache下運行。
- getcwd()和
__DIR__
都回傳正確的目錄/var/www/html/myproject。
- dirname(
__FILE__
)傳回檔案的正確絕對路徑
- 檢查file_exists($_FILES['file']['tmp_name'])回傳true
- 檢查$_FILES['file']['error'](我要移動的檔案)回傳0,上傳沒有問題。
- 使用is_writable("/tmp")檢查來源資料夾(/tmp)是否可寫,回傳true。
- 嘗試在test/上暫時使用chmod -R 777,仍然顯示權限被拒絕且不可寫入。
- 暫時禁用了防毒/EDR
- 檢查「test/」的安全上下文。傳回結果為:「unconfined_u:object_r:httpd_sys_content_t:s0」。這些都不是問題(在下面的回覆中有解釋)。
- 檢查是否安裝了可能阻止行動檔案的安全相關應用程式。這些應用程式未安裝:AppArmor、grsecurity、Tomoyo Linux和Smack。
- 在php腳本中使用fopen() / flock()函數確認我要移動的檔案沒有被鎖定。
- 使用is_uploaded_file()函數確認我正在嘗試移動一個上傳的檔案(在這一點上我已經快瘋了,只是嘗試我能想到的任何方法)。當然,這回傳true。
move_uploaded_file需要兩個參數。 1:你想要上傳的文件 2:放置檔案的絕對路徑 3:請確保上傳目錄具有適當的所有權和權限(注意:如果您使用Apache作為代理,目錄所有權應屬於apache2的使用者:群組)。
閱讀更多:https://www.php.net/manual/pt_BR/function.move-uploaded-file.php