iT邦幫忙

0

[php,檔案處理]file_exists判斷中文檔名行為異常

file_exists對於英文檔名行為正常,但對於中文檔名雖然不會出錯但行為異常
網路上查到的大多是需要進行轉碼動作,但還是無法動作,

想詢問各位前輩們要怎麼解決中文問題或有沒有其他的替代方式???

環境: php 5.6 / win10
編碼:檔案UTF-8 / 作業系統Big5

測試代碼

$tmp1 = 'C:\\VisualHosts\\storage\\539\\餐飲技術.jpg';
//$tmp1 = 'C:\\VisualHosts\\storage\\539\\AAA-_.jpg';
$tmp2 = file_exists($tmp1);
$tmp3 = exif_imagetype($tmp1);

$tmp4 = mb_convert_encoding($tmp1, 'big5');
$tmp5 = file_exists($tmp4);
$tmp6 = exif_imagetype($tmp4);

$tmp7 = iconv('utf-8', 'big5', $tmp1);
$tmp8 = file_exists($tmp7);
$tmp9 = exif_imagetype($tmp7);

$tmp10 = mb_convert_encoding($tmp1, 'cp1252');
$tmp11 = file_exists($tmp10);
$tmp12 = exif_imagetype($tmp10);

$tmp13 = iconv('utf-8', 'cp1252', $tmp1);
$tmp14 = file_exists($tmp13);
$tmp15 = exif_imagetype($tmp13);

目前測出來的結果

變數 餐飲技術.jpg AAA-_.jpg
$tmp2 false true
$tmp3 false 2
$tmp4 "C:\VisualHosts\storage\539\�\���޳N.jpg" "C:\VisualHosts\storage\539\AAA-_.jpg"
$tmp5 false true
$tmp6 false 2
$tmp7 "C:\VisualHosts\storage\539\�\���޳N.jpg" "C:\VisualHosts\storage\539\AAA-_.jpg"
$tmp8 false true
$tmp9 false 2
$tmp10 "C:\VisualHosts\storage\539\????.jpg" "C:\VisualHosts\storage\539\AAA-_.jpg"
$tmp11 false true
$tmp12 false 2
$tmp13 false "C:\VisualHosts\storage\539\AAA-_.jpg"
$tmp14 false true
$tmp15 false 2
看更多先前的討論...收起先前的討論...
fillano iT邦超人 1 級 ‧ 2020-02-14 14:37:25 檢舉
先確認php程式檔案編碼,如果這裡就跟你預期的不一樣,後面怎麼測試可能都不對。

另外,你要確定檔案系統使用的是怎樣的編碼,因為你是對檔案系統操作。

輸出到畫面(瀏覽器)看到的東西,又是另外一回事。
舜~ iT邦好手 1 級 ‧ 2020-02-14 14:49:01 檢舉
檔案UTF-8 環境win10是Big5
fillano iT邦超人 1 級 ‧ 2020-02-14 18:09:14 檢舉
用php7
淺水員 iT邦新手 1 級 ‧ 2020-02-15 00:30:29 檢舉
真的跟版本有關喔?因為我手邊是 php7+win10
PHP直接用UTF8寫中文檔名的確是沒問題的
不過還沒時間測試5.6的所以沒回應這篇
fillano iT邦超人 1 級 ‧ 2020-02-15 07:35:15 檢舉
我簡單測試過,用php7沒問題,但是php5.6就...
fillano iT邦超人 1 級 ‧ 2020-02-15 09:52:38 檢舉
應該說7.1沒問題,我回應了XD
舜~ iT邦好手 1 級 ‧ 2020-02-15 10:50:33 檢舉
想換...而且聽說php7的性能比php5.6快了近2倍~~~
vegalou iT邦新手 4 級 ‧ 2020-02-15 20:42:55 檢舉
壞習慣,中文檔名,請問,如果你的code要global,誰看得懂你的檔案名稱?

POST出來就應該索引 encode, base64還是base32編碼標準化,顯示再解碼還原。
2
mlck970677
iT邦新手 5 級 ‧ 2020-02-14 13:38:50

$tmp4 = mb_convert_encoding($tmp1, 'UTF-8');

舜~ iT邦好手 1 級 ‧ 2020-02-14 14:49:42 檢舉

謝謝您,雖然沒成功,連結晚點看

2
firecold
iT邦新手 3 級 ‧ 2020-02-14 14:19:19

建議編寫資料庫
將原始檔名另外存起來
然後不管是比對檔案是否重複
還是下載在組合原始檔名都可以

也能避免檔案覆蓋跟中文異常

1
ckp6250
iT邦新手 2 級 ‧ 2020-02-14 17:30:23

我覺得問題不在 file_exists 這個函數上耶,
因為我的壞習慣是,很常使用中文檔名,當然也很常使用 file_exists
沒出過問題啊,算我運氣好。

或許是 Linux+php 的關係吧,兩者環境相同,都是 utf8。

3
小魚
iT邦大師 1 級 ‧ 2020-02-14 17:54:07

印象中,
網頁上的檔案,
本來就是要避免使用中文,
中文通常是存資料庫另外作說明,
也就是說明是中文,
但是檔名是英文(或是隨機字串).

看更多先前的回應...收起先前的回應...
ckp6250 iT邦新手 2 級 ‧ 2020-02-14 20:48:09 檢舉

  我存在 Google 雲端硬碟上的檔案,也都使用中文檔名,也沒出過問題。

  我是想,【顧名思義】很重要,如果一個檔名沒辦法望文生義,那麼久而久之,肯定不知所云。

  早年的作業系統,中文檔名常會出槌,使得大家不太敢用,如今應該無此顧忌才對,除非您的檔案是要給外國人。

淺水員 iT邦新手 1 級 ‧ 2020-02-15 00:25:29 檢舉

照小魚說的方式,使用者並不會知道實際上是用中文還是英文存的。
並不會有「沒辦法望文生義」的問題。

slime iT邦大師 1 級 ‧ 2020-02-15 09:15:28 檢舉

其實 Google 也沒有用中文"檔名", 而是一串文件代號, "檔名"只是給使用者習慣對照用的.

例如: Google 文件分享時, 出現的網址, 當中一部份就是文件代號, 還有一部份是分享格式.

google的雲端硬碟存的一定不是中文檔名。只是讓你看到的是中文檔名。不要誤會了。

ckp6250 iT邦新手 2 級 ‧ 2020-02-15 15:42:52 檢舉

了解啦,謝謝各位。

2
fillano
iT邦超人 1 級 ‧ 2020-02-15 09:18:29

查了一下php7的change log:
https://www.php.net/ChangeLog-7.php

php-7.1.0修了一個bug:

Fixed UTF-8 and long path support on Windows.

這之後的版本就沒問題。7.0.33(應該是7.0最後一版?)還是會有問題。

舜~ iT邦好手 1 級 ‧ 2020-02-15 10:51:49 檢舉

感恩,長知識了,不過短時間內版本換不了 ><

1
浩瀚星空
iT邦大師 1 級 ‧ 2020-02-15 11:52:07

基本上如果可以從上傳下手,就會從上傳中下手讓實際檔名不是中文。
不過比較常遇到的是提供ftp上傳。
或是直接網芳上傳。這些都容易碰到中文檔名的問題沒錯。

我早期曾經的做法給你參考。
當獲取的檔名中,有發現非英數及一些符號時。
會先用正則檢查是否為中文。

不是中文的話,會試著用big5、gb2312、iso這些編碼轉換一次試試。
直到用正則能判斷為中文為止。

我要發表回答

立即登入回答