2012-03-15 100 views
0

我想要做的是轉換一些存檔的CSV數據。它在幾千個文件上運行得很好。我解析出日期並將其轉換爲時間戳。然而,在一個文件中,它不能工作。我使用(int) $string將解析的字符串轉換爲int值 - >它返回int(0)。我也用intval() - >相同的結果。當我使用var_dump($string)時,我得到了一些奇怪的輸出,例如string(9) "2008",實際上應該是string(4) "2008"。我試圖在字符串上使用preg_match,但沒有成功。這是一個編碼問題?PHP解析/類型轉換問題

下面是一些代碼,它只是非常標準的東西:

date_default_timezone_set('UTC'); 
$ms = 0; 
function convert_csv($filename) 
{ 
$target = "tmp.csv"; 
$fp = fopen("$filename","r") or die("Can't read the file!"); 
$fpo = fopen("$target","w") or die("Can't read the file!"); 
while($line = fgets($fp,1024)) 
{ 
    $linearr = explode(",","$line"); 

    $time = $linearr[2]; 
    $bid = $linearr[3]; 
    $ask = $linearr[4]; 
    $time = explode(" ",$time); 
    $date = explode("-",$time[0]); 
    $year = (int) $date[0]); 
    $month = (int)$date[1]; 
    $day = (int)$date[2]; 
    $time = explode(":",$time[1]); 

    $hour = (int)$time[0]; 
    $minute = (int)$time[1]; 
    $second = (int)$time[2]; 
    $time = mktime($hour,$minute,$second,$month,$day,$year); 

    if($ms >= 9) 
    { 
     $ms = 0; 
    }else 
    { 
     $ms ++; 
    } 
    $time = $time.'00'.$ms; 
    $newline = "$time,$ask,$bid,0,0\n"; 
    fwrite($fpo,$newline); 

} 
fclose($fp); 
fclose($fpo); 
unlink($filename); 
rename($target,$filename); 

}

下面是對文件的鏈接,我們正在談論:

+1

請給我們看一些代碼。你也得到了'string(9)「2008」'? – Dogbert 2012-03-15 12:13:11

+0

字符串的十六進制轉儲肯定是一個好主意,因爲看起來太高的字符串長度表示存在輸出查看器不能或不會顯示的字節。 – 2012-03-15 12:16:51

+0

感謝您的意見,我只是添加了代碼! – user871784 2012-03-15 12:19:29

回答

2

該文件似乎被編碼在UTF-16,所以確實是一個編碼問題。如果UTF-16被解釋爲單字節編碼,則string(9)是由您獲得的空字節引起的。

由於它們是二進制安全的,因此無法識別編碼,因此這使得文件很難用fgets等函數進行讀取。您可以讀取內存中的整個文件並執行編碼轉換,但這非常低效。

我不確定是否可以使用原生PHP函數以UTF-16正確讀取文件。您可能需要編寫或使用外部庫。

+0

哈哈謝謝,我明白了這一秒!:) – user871784 2012-03-15 12:31:21

0

您可以嘗試使用iconv轉換文件以規劃ascii。

如果您是有iconv命令在Linux或類似的系統:

$的iconv -f -t UTF-16 ASCII EUR_USD_Week1.csv> clean.csv

否則,你可能會發現PHP的iconv功能有用:

http://php.net/manual/en/function.iconv.php