PHP fgetcsv讀取CSV檔案(支援中文語系)
CSV(Comma Separated Values)是一種逗號分隔純文字檔案
通常用在不同軟體介面交換資料時使用(例如Yahoo、Microsoft Outlook 及 Google)
像是電話簿資料、簡訊或信箱內容,都可以當作不同介面交換的一種方式
因為一般人慣用CSV,所以當然在撰寫網頁時可能會使用到以程式讀取CSV檔案再寫入資料庫
在PHP程式語言中,就有這麼一個簡單的函式可供使用
我們稱它為【fgetcsv】
相信使用過的人都知道,在讀取中文時可能會發生遺失字串的情況
例如讀取的資料是「台中-奧義資訊」
但經過PHP原生的fgetcsv解析後
發現只會剩下「-奧義資訊」
這好像是原生函式的錯?
也聽說在PHP4時沒有問題
PHP5初會發生亂碼
而我碰到的是字串直接消失
然而我發現跟PHP環境有很大的關係(應該是版本的問題)
那當然網路上有很多人已經解決了
有的人是用【setlocale】
但大部分看到或是我親自測試都是無效的(或是檔案編碼問題)
那麼結果就是重寫函式自己套用
以下是程式,直接複製使用
/**
* fgetcsv
*
* 修正原生fgetcsv讀取中文函式
*
* @param CSV文件檔案
* @param length 每一行所讀取的最大資料長度
* @param d 資料分隔符號(預設為逗號)
* @param e 字串包含符號(預設為雙引號)
* @return $_csv_data
*/
function __fgetcsv(&$handle, $length = null, $d = ",", $e = '"') {
$d = preg_quote($d);
$e = preg_quote($e);
$_line = "";
$eof=false;
while ($eof != true) {
$_line .= (empty ($length) ? fgets($handle) : fgets($handle, $length));
$itemcnt = preg_match_all('/' . $e . '/', $_line, $dummy);
if ($itemcnt % 2 == 0){
$eof = true;
}
}
$_csv_line = preg_replace('/(?: |[ ])?$/', $d, trim($_line));
$_csv_pattern = '/(' . $e . '[^' . $e . ']*(?:' . $e . $e . '[^' . $e . ']*)*' . $e . '|[^' . $d . ']*)' . $d . '/';
preg_match_all($_csv_pattern, $_csv_line, $_csv_matches);
$_csv_data = $_csv_matches[1];
for ($_csv_i = 0; $_csv_i < count($_csv_data); $_csv_i++) {
$_csv_data[$_csv_i] = preg_replace("/^" . $e . "(.*)" . $e . "$/s", "$1", $_csv_data[$_csv_i]);
$_csv_data[$_csv_i] = str_replace($e . $e, $e, $_csv_data[$_csv_i]);
}
return empty ($_line) ? false : $_csv_data;
}
原本在程式中使用fgetcsv($csv_file)
只要改為__fgetcsv($csvfile)即可
資料來源: http://herolin.twbbs.org/entry/fgetcsv-chinese-solution-for-php/
so cool!
感謝大大