2016-04-15 50 views
0

我正在努力培養對php的理解,並非常感謝任何幫助。我使用了一個while循環來比較我的表單中發佈的一些值與存儲在csv文件中的值。 此代碼運行良好。但是,是否有可能使用FOR EACH循環或甚至Do Until?來實現相同的結果?或兩者??對於任何支持PHP中的while循環的替代方案

$file_handle = fopen("games.csv", "r"); # identify which file is being used. 
while(!feof($file_handle)) 
{ 
$gameinfo = fgetcsv($file_handle); 
if ($gameinfo[0] == $_POST["gameID"]) 
{ 
$GameName = "$gameinfo[2]"; 
$GameCost = "$gameinfo[4]"; 
$GameFound = true; 
} 
} 
fclose($file_handle); 
+1

不,從文件句柄讀取,而唯一合理的構造。 Foreach需要知道結構的大小以提前循環,並且儘管總是要執行至少一個循環,即使文件長度爲0也是如此。 – GordonM

+0

一旦你找到了遊戲,我可能會傾向於跳出循環,而不是繼續循環....並且你爲什麼在引號中包裝'$ gameinfo [2]'和'$ gameinfo [4]' ''' –

+0

@GordonM啊我看到了,所以每個循環都不可能確定迭代的次數,然而,爲什麼在執行循環時至少執行一次,即使文件是0長度 - 你的意思是這個程序只是在浪費時間嗎? – MissDizy

回答

2

while非常感謝是這個任務最適合的語句,因爲你想要做任何讀取之前檢查EOF

可以作爲練習變換它在do-while(PHP中沒有do-until):

do 
{ 
    if (!feof($file_handle)) 
    { 
     $gameinfo = fgetcsv($file_handle); 

     if ($gameinfo[0] == $_POST["gameID"]) 
     { 
     ... 
     } 
    } 
} 
while(!feof($file_handle)); 

或更短

do 
{ 
    if (feof($file_handle)) 
     break; 

    $gameinfo = fgetcsv($file_handle); 

    if ($gameinfo[0] == $_POST["gameID"]) 
    { 
     ... 
    } 
} 
while(true); 

但是這只是寫一個while一個不錯的方法。

關於foreach,引用該文檔

foreach構造提供了一種簡單的方法來遍歷陣列。 foreach僅適用於數組和對象,並且當您嘗試在具有不同數據類型或未初始化變量的變量上使用它時會發出錯誤。

您可以customize iteration over objects,這讓你(警告,深入淺出)上的「自定義對象」使用foreach這樣就可以,在某種程度上,延長foreach功能。
例如遍歷CSV文件,你可以使用這個類

<?php 
class FileIterator implements Iterator 
{ 
    private $file_handle = null; 
    private $file_name; 
    private $line; 

    public function __construct($file_name) 
    { 
     $this->file_name = $file_name; 

     $this->rewind(); 
    } 

    public function rewind() 
    { 
     if (!is_null($this->file_handle)) 
      fclose($this->file_handle); 

     $this->line = 1; 
     $this->file_handle = fopen($this->file_name, "r"); 
    } 

    public function current() 
    { 
     return fgetcsv($this->file_handle); 
    } 

    public function key() 
    { 
     return $this->line; 
    } 

    public function next() 
    { 
     return $this->line++; 
    } 

    public function valid() 
    { 
     $valid = !feof($this->file_handle); 

     if (!$valid) 
      fclose($this->file_handle); 

     return $valid; 
    } 

} 
?> 

,並使用這種方式

$it = new FileIterator("game.csv"); 

foreach ($it as $line => $gameObj) 
{ 
    echo "$line: " . print_r($gameObj, true) . "<br/>"; 
} 

即產生類似

1: Array ([0] => 0 [1] => Far Cry 3) 
2: Array ([0] => 1 [1] => Far Cry Primal) 
3: Array ([0] => 2 [1] => Alien Isolation) 

此文件

0,Far Cry 3 
1,Far Cry Primal 
2,Alien Isolation 
+0

非常感謝您花時間回答我的問題。爲每個將花我一點時間來讓我的頭,但真的很感激 – MissDizy

+0

我想你可以使用file()和foreach作爲另一種方式做foreach(file(「file_name_goes_here」)作爲$ line) '但這意味着將整個文件加載到內存中以創建該數組。大文件=大內存使用量。 – GordonM

+1

@MissDizy擴展以前的評論,有一個更簡單的方法(感謝http://se1.php.net/manual/en/function.str-getcsv.php#114764):'foreach(array_map('str_getcsv' ,file('data.csv')))'。 – cFreed