2016-02-10 80 views
0

我正在玩一個將統計數據導出到CSV文件的視頻遊戲。解析PHP中的CSV文件

http://pastebin.com/FPzJ3Qz7

第5行是我的頭/表。

我有一個存儲數據的PHP/MySQL數據庫...

我的問題是,每次我需要刪除前4行,以及所有的那些線498後的時間。因爲我只對它們之間的數據感興趣。

行號可以每次都改變。

我可以使用正則表達式來匹配我需要的部分,但是當我使用file_get_contents時,它會刪除新行,並生成一個大字符串。

最終我的目標是,將CSV上傳到Web服務器,運行cron加載PHP腳本,解析出CSV,然後運行SQL語句讀取CSV並更新/插入數據庫。

有什麼建議嗎?

+2

歡迎來到SO。 請閱讀[我可以問哪些主題](http://stackoverflow.com/help/on-topic) 和[如何提出一個好問題](http://stackoverflow.com/help/how-to - 問) 和[完美的問題](http://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/) SO是**不是免費的編碼或教程服務* *你必須表明你已經努力解決你自己的問題。 – RiggsFolly

+0

除了@ RiggsFolly的評論,這個問題已經解決了幾次 - ['str_getcsv()'](http://php.net/manual/en/function.str-getcsv.php)或['explode ()'](http://php.net/manual/en/function.explode.php)將是一個很好的起點(並且會通過簡單的搜索來顯示自己...) – Jan

+2

如果你使用cron來運行這個任務,你甚至不需要使用PHP。使用'head'和'tail'來提取你需要的文件部分,然後使用'mysql'的'LOAD DATA INFILE'加載它。 –

回答

1

如果您使用file()而不是file_get_contents(),那麼您將得到一個數組,其中每行代碼都有一個值。從此處開始,您可以使用array_search()來查找您的分隔符所在的位置,然後使用array_splice()將相關部分的數據着陸。

但是,由於您已經批量提取相關部分,所以這非常簡單。 $entries = explode("\n", $bulk);會給你一個數組上的每行數據。

然後你可以迭代你的數組,例如使用explode(',', $entryline)將每個數據字符串解析爲一個數組。還有str_getcsv(),但在您的情況下,您必須勾選默認機箱,因爲您的數據未公開。然後將其插入數據庫中的匹配字段。

MySQL也可以直接導入CSV數據,如:LOAD DATA INFILE '/scores.csv' INTO TABLE tbl_name FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n' IGNORE 4 LINES; - 雖然你最終必須擺脫塊,但這是爲了統一的CSV數據。

[如果你有工作,你正在試圖解決這個代碼,將其添加到你的問題尋求更多幫助。]

+0

嘿,那裏,迄今爲止最好的評論...這是我目前的代碼,根據你所說的。 array_search雖然給我一些問題。 [鏈接](http://pastebin.com/VRTnb4H0) – rolomcflurry

+0

在不幸的第13行的分隔符後面有一個空格。如果刪除它,'array_search'會給你'int(531)'。 ;)你不需要做'$ stats2 = array_slice($ stats,4);',你可以簡單地'$ stats = array_slice($ stats,4);'或者使用'array_splice',保存每個版本不同變量中的數據會消耗內存。 –

+0

嗯,我刪除了空間,它仍然不會顯示任何東西?並感謝$ stats/$ stats2 – rolomcflurry

0

嘗試使用PHP函數file(),該函數將文件作爲數組獲取 - 每行都是數組中的元素。然後,您可以循環開始和結束任何需要的行。

+0

['str_getcsv()'](http://php.net/manual/en/function.str-getcsv.php)也會派上用場。 – Jan

1

不必加載的所有文件(使用白白內存),你可以逐行讀取文件(作爲流)並構建一個生成器函數,它可以逐個返回您感興趣的記錄。這樣你不需要刪除,你只需要使用條件並選擇你想要的。示例:

function getLineFromFileHandler($fh, $headers = false) { 
    // initializations 
    $sectionSeparator = str_repeat('-', 62); 
    $newline = "\r\n"; 
    $sectionSeparatorNL = $sectionSeparator . $newline; 
    $rowSeparatorNL = ',' . $newline; 

    // skip title/subtitle (feel free to add a param to yield them) 
    $title = stream_get_line($fh, 4096, $sectionSeparatorNL); 
    $subtitle = stream_get_line($fh, 4096, $sectionSeparatorNL); 

    // get the field names 
    $fieldNamesLine = stream_get_line($fh, 4096, $rowSeparatorNL); 

    // return the records 
    if ($headers) { 
     $fieldNames = array_map('trim', explode(',', $fieldNamesLine)); 

     while (($line = stream_get_line($fh, 4096, $rowSeparatorNL)) !== false && 
       strpos($line, $sectionSeparator) === false) 
      yield array_combine($fieldNames, explode(',', $line)); 
    } else { 
     while (($line = stream_get_line($fh, 4096, $rowSeparatorNL)) !== false && 
       strpos($line, $sectionSeparator) === false) 
      yield explode(',', $line); 
    } 
} 

$fh = fopen('csv.txt', 'r'); 

foreach(getLineFromFileHandler($fh, true) as $record) 
    print_r($record); 

fclose($fh); 

此示例將每條記錄顯示爲關聯數組,其中字段名稱爲鍵。正如你所看到的,你可以刪除生成器函數的第二個參數來獲得索引數組。隨意選擇最方便的方式將記錄插入到數據庫中(逐個,逐塊或全部一次性)。

+0

如果我們正在處理其中一個大型垃圾堆,這將是確定的方法。但是,如果它只有幾十KB文件,它可能不是非常重要的記憶方式。當然,瞭解你未來的數據並且設置爲放大。如果你一次加載了以兆字節爲單位的CSV,那麼不要做你所做的就是一個殺手,1MB的原始數據很容易在RAM中增加10倍,特別是少量整數會增加陣列的內存容量。 –