2016-12-14 105 views
-3

我對PHP中的Strtok()函數非常熟悉,並且我沒有問題讓函數在過去對字符串正常工作。但是,我現在必須閱讀一個.csv文本文件(我已經成功完成),每行由6個字段組成,如:姓,名,地址,城市,地區,郵政編碼\ r \ n < - 回車和換行結束PHP-strtok(),關聯數組關係

我必須使用Strok()來分隔這些分隔符,並將字段標記爲字段(即最後一個,第一個,地址等)。我打算使用一個使用姓氏作爲主鍵的關聯數組,以便我可以將數據插入到已創建並正在工作的HTML表中。我現在的問題是正確地分割文件,因爲它具有由這6個字段組成的約200行,並將字符串作爲字段正確存儲到數組中,所以數據結構就是我遇到問題的地方。這是我到目前爲止有:

$inputFile = fopen("input.csv","r"); 
    $delimiters = ","; 
    $token = strtok($inputFile, $delimiters); 
    $n=1; 

    while ($token){ 
     echo "Token $n: $token <br>"; 
     $token = strtok($delimiters); 
     $n++; 
    } 

顯然,下面的表格中它創建,但因爲我沒有做過的數據結構相當,但,我沒有爲它的字段。我認爲我的令牌循環對於這個問題可能不正確,但是我從我的書中的一個早期例子中抽出一些,並且在我的令牌過程工作但文件結構不同的情況下進行了練習。感謝您的任何指示或幫助。

+0

什麼是CSV的例子線和你在哪裏得到這些「字」作爲關聯數組鍵使用? – AbraCadaver

+0

基本上每行都包含這6個值,然後返回到下一個值。這裏有兩個例子: –

+0

SELBY,AARON,1519 Santiago de los Caballeros Loop,Mwene-Ditu,East Kasai,22025 GOOCH,ADAM,230 Urawa Drive,Adoni,Andhra Pradesh,2738 –

回答

0

有CSV函數在PHP,像fgetcsv,所以這真的是錯誤的做法推倒重來。

請注意,在您的代碼中,您實際上沒有讀取文件的內容,因爲您只能獲取文件指針。

如果你真的需要strtok要做到這一點,你的CSV很簡單,在這個意義上,它並沒有被引用的字符串,這可能嵌入的分隔符,你可以使用:

  • file_get_contents()在一個字符串中讀取文件內容。當然,file()會讓你更容易,因爲它已經拆分線。但我認爲,如果CSV功能不適合你,那麼這兩者都不會。

  • strtok用於獲取領域,但在循環的末尾,而不是在開始時,因爲與雙參數的初始呼叫已檢索循環之前的第一個值。

代碼:

$input = file_get_contents("input.csv"); 
$delimiters = ",\n\r"; 

$token = strtok($input, $delimiters); 
$result = []; 
$row = []; 
while ($token){ 
    echo "Token $token <br>"; 
    $row[] = $token; 
    if (count($row) == 6) { // write record 
     $result[] = $row; 
     $row = []; 
    } 
    $token = str_replace('\r', '', strtok($delimiters)); 
} 

print_r($result); 

請注意,這不會產生關聯數組。如果你需要,然後使用此代碼:

$columns = ['last', 'first', 'address1', 'address2', 'address3', 'zip']; 

,然後在你的循環,通過更換$row[] = $token

 $row[$columns[count($row)]] = $token; 

你可以看到eval.in該版本運行。您在評論中提供的數據的輸出爲:

Array (
    [0] => Array (
     [last] => SELBY 
     [first] => AARON 
     [address1] => 1519 Santiago de los Caballeros Loop 
     [address2] => Mwene-Ditu 
     [address3] => East Kasai 
     [zip] => 22025 
    ) 
    [1] => Array (
     [last] => GOOCH 
     [first] => ADAM 
     [address1] => 230 Urawa Drive 
     [address2] => Adoni 
     [address3] => Andhra Pradesh 
     [zip] => 2738 
    ) 
) 

再次,這不可取。你應該使用fgetcsv。這也更好地處理可能帶有逗號,雙引號或甚至換行的字符串。

+0

謝謝,這絕對能讓我走上正確的道路。我也完全理解了這個問題,因爲我發現了幾種無縫的方法來做到這一點。出於某種原因,我的教授決定使用一個。csv文件來顯示令牌的功能,但是這對我來說是丟失的。一個問題:這在我的表格中顯示空白郵政領域,但是當我打印我的結果時它們顯示一個標記。這可能與計數($行)部分有關嗎? –

+0

我看不到這樣的問題。我在答案中添加了代碼鏈接,您可以在其中檢查* $ result *數組的內容是否正確幷包含郵政編碼。可能在生成表的代碼中有另一個問題。你可以隨時引入一個新的問題。 – trincot

0

好吧,我會跳過,因爲fgetcsv()這個問題,但我很無聊:

$lines = file($inputFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); 
$delimiters = ","; 

foreach($lines as $line) { 
    $values = array(strtok($line, $delimiters)); 
    while($token = strtok($delimiters)){ 
     $values[] = $token; 
    } 
    $result[] = $values; 
} 
  • 讀取文件中的行到一個數組
  • 循環得到每一行,並把第一個令牌行成一個值的數組
  • 環行,並得到所有標記,並添加到值陣列
  • 添加值的數組導致陣列

我加了一個array_combine(),因爲你說了關於關聯數組的一些東西。如果需要,可以使用這樣的事情:

$result[] = array_combine(array('last name', 
            'first name', 
            'address', 
            'city', 
            'district', 
            'postal code'), $values); 

如果你想是爲每個結果行的關鍵,因爲鑰匙是獨一無二的,我不認爲你可以保證最後這是不可取名稱是唯一的:

$result[$values[0]] = $values; 
    //or to remove it from the array but use as the key 
    $result[array_unshift($values)] = $values; 
+0

對於自「間隔」以來仍然*錯誤的內容,「This」「Thing」「」''是有效的CSV,具體取決於您對「有效」和「CSV」的定義。 – tadman

+0

不,屎!不會看到我「使用」它。 ; -0 – AbraCadaver

+0

是的,這對解析嚴格逗號分隔的值非常有用,但不適用於CSV文件。 – tadman