# file_upload 遇到水坑_知道救你命
###### tags: `檔案上傳` `問題` `FormData` `jQuery` `Ajax`
- Illegal invocation(Error)
- processData jQ默認自動處理Data屬性資料 並序列化
- contentType jQ默認屬性
- contentType
- datatype
- multipart/form-data
- 表明表單上傳檔案的二進制資料
- multipart/form-data 與contentType 與FormData 關係
- ------------------
- is_file 與file_exists 差異
- move_uploaded_file 失敗
- ---------------------
- 權限問題
- 777 與 755 是甚麼?
- failed to open stream permission denied in php(move_uploaded_file給出“無法打開:權限被拒絕”錯誤)
<br><br>
---
---
今天做上傳檔案,怎模都做不出來
十分奇怪,即使寫過很多次
所以在寫一次
<br><br>
## Illegal invocation(Error)
遇到了一樣了問題
導致jq無法發ajax
經過排查是第三個問題,也就是file檔被JQ預先處理了!
程式碼:
```javascript=
function clickfile(){
var file = document.getElementById('file').files[0];
console.log(file); // 確認抓到檔案
var fd = new FormData();
fd.append('file', file);
for (var key of fd.entries()) {
console.log(key[0] + ', ' + key[1]);
} // 確認檔案是否append
$.ajax({
type: "POST",
url: "ajax.php",
data: fd,
cache: false,
contentType: false, // 這行要加不然php不能直接抓到$_FILE 改成下面的一樣抓不到
//contentType: "multipart/form-data",
processData: false, // 不預先處理formData(參數)
// processData 預設 true => jQuery處理data屬性並將值轉換為字符串。
success: function(re){
console.log(re);
}
})
}
```



----


### 參考資料
[Ajax上传文件/照片时报错TypeError :Illegal invocation](https://segmentfault.com/a/1190000017832617)
[jquery ajax报Uncaught TypeError :Illegal invocation](https://blog.csdn.net/suhui1995/article/details/78010646)
<br><br><br>
## contentType
>**Ajax內設定 contentType: multipart/form-data
!!不需要!! 再HtmlForm元素中再設定一次了**
**選一個設定就可以了**
<br><br><br>
## datatype
<br><br><br>
## multipart/form-data 與contentType 與FormData 關係
-----
<br><br><br>
## is_file 與file_exists 差異
**正常寫fileupload時是使用`file_exists` 但其實這樣檢查是有問題的
`file_exists`是檢查路徑資料夾存不存在並不適檢查檔案
`is_file` 是檢查是否為file**

```javascript=
ini_set('display_errors','on'); # 開啟錯誤輸出
error_reporting(E_ALL & ~E_NOTICE); # 設定輸出錯誤類型
echo $_FILES['file']['name'];
echo $_FILES['file']['type'];
echo $_FILES['file']['suze'];
echo $_FILES['file']['tmp_name'];
var_dump(file_exists('D:\carrefour_care\upimg')); //檢查目錄在不在 檔案不在裡面
var_dump(is_file("D:\carrefour_care\upimg\\" . $_FILES['file']['name']));
var_dump(is_file($_FILES['file']['tmp_name']));
echo "D:\carrefour_care\upimg\\" . $_FILES['file']['name'];
var_dump($_FILES['file']['name']);
```
### 重點
同一份code下
在剛剛的`D:\carrefour_care\_public\ajax.php:24` 加入同一份檔案
原本false > true
所以`is_file`才是真正有檢查檔案的
```javascript=
is_file($_FILES['file']['tmp_name']) // 上傳到臨時目錄 $_FILES['file']['tmp_name']是臨時目錄的path
```

### 參考資料
[PHP 的 is_file() 及 file_exists()](https://www.opencli.com/php/php-is_file-file_exists)
[is_file or file_exists in PHP](https://stackoverflow.com/questions/792899/is-file-or-file-exists-in-php)
<br><br><br>
## move_uploaded_file 失敗
檔案上傳成功了!但卻一直無法移動檔案
原來是權限問題
### 檢查檔案權限
移動到目錄用`ls -l` 查詢文件夾權限

設定權限為777 跟755做測試

文件上傳成功


777權限太過危險
改成設定對象為apaech 用於控制使用者對檔案的權限的命令
[hmod](https://zh.wikipedia.org/wiki/Chmod)

文件上傳成功了,不過有時隔天就又不行了

-----
## 權限問題
### 請不要設定權限為777很危險

## 777 與 755 是甚麼?
-----
<br><br><br>
## failed to open stream permission denied in php(move_uploaded_file給出“無法打開:權限被拒絕”錯誤)
同樣改完當天可以,隔天又不行了!
得很頭痛
直接硬改能用在說
[move_uploaded_file gives “failed to open stream: Permission denied” error](https://stackoverflow.com/questions/8103860/move-uploaded-file-gives-failed-to-open-stream-permission-denied-error)
[php遇到failed to open stream: Permission denied](https://blog.csdn.net/daily886/article/details/82803554)