今天遇到一個在 Load balancer 上的網站,採用 PHP 5 的 A 主機網頁正常,但使用 PHP 7 的 B 主機版面就怪怪的。追蹤了一下,看起來是 fgetcsv() 出問題,沒有正常解析。我們的 CSV 檔是 Big5 編碼的,看起來是解析了某個中文欄位之後,後續欄位就有異常。
上網查了一下,找到《PHP讀取BIG5編碼的CSV檔》,裡面提到:
「但如果 CSV 檔是 BIG5 編碼,當中文字中有包含反斜線(\)字元的衝碼字,
可能會使 fgetcsv() 解析出來的資料欄位數量不正確。
可發現第 5 個脫逸參數預設是反斜線(\),所以當解析到包含反斜線(\)的 BIG5 中文字時,
雖然可以解析,但解析出來的資料不是預期的,該行解析出的欄位數也會是錯的。」
因為 PHP7 的 fgetcsv() 和 PHP5 fgetcsv() 的參數個數不同,所以要加上這樣的 function:
<?php
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;
}
?>
加好就沒事了~
文章標籤
全站熱搜
留言列表