簡體   English   中英

PHP-SplFileObject-使用seek()方法時第二行輸出錯誤

[英]PHP - SplFileObject - Wrong output for second line when using seek() method

轉到UPDATE來閱讀實際的問題。 Bert Peters提交的第一個答案已經解決了舊問題。

老問題:我有幾個文件名為file.1.txt,file.2.txt,file.3.txt,...。我正在使用SplFileObject讀取第一個文件,並使用foreach循環遍歷其內容:

$file = new SplFileObject("file.1.txt");
foreach ($file as $row) {
  // ...
}

根據我正在讀取的第一個文件的內容,可能會讀取或可能不會讀取其他文件。 在所有情況下,下一步都只能使用另一個文件(file.2.txt或file.3.txt)。 因此,在foreach循環中的某處存在if語句來處理此問題。

所有文件都具有相同的結構,因此會出現問題。 我不想創建新的foreach來讀取下一個文件-就像我寫的那樣,可能根本不需要它,所以我想使用現有的foreach而不是編寫新的。 是否有可能用其他文件的內容覆蓋$ file變量,並僅使用一個foreach或任何其他循環對其進行迭代? 例如:

foreach ($file as $row) {
  // ...
  if ($contentContainsSomething) {
    $file = new SplFileObject("file.2.txt");
    // somehow reset foreach to read file.2.txt from start
  }
}

我不想使用goto語句解決此問題。 遞歸似乎是適當的解決方案,但是如果有一種方法可以動態地在循環中更改對象,則我更喜歡這種解決方案。

更新:如“老問題”中所述,所有使用的文件(file.1.txt,file.2.txt,...)都具有相同的結構,因此這就是為什么我不想編寫更多相同的循環和復制代碼的原因。 相反,我使用了@Danack中的代碼(由他在SO聊天中建議),該代碼已經成為解決方案的一部分。 這是無需額外升級即可讀取更多文件的基本代碼:

$path = "file.1.txt";
$whileCounter = 0;
while ($path != null) {
  $file = new SplFileObject($path);
  $file->setFlags(SplFileObject::READ_CSV);
  $file->setCsvControl("\t");
  $path = null;
  foreach ($file as $rowKey => $row) {
    // echo row  }
  $path = "file.2.txt";
  if ($whileCounter > 0) {
    break; // solution to stop loop, just for now
  }
  $whileCounter++;
}

因此,此代碼可以正常工作,並按預期輸出文件的行。 問題是當我想使用seek()方法讀取文件的下一行時,因為我想對附加到每一行的某些信息做出決定。 因此,如果我使用seek($ rowKey +1)來幫助我獲取下一行數據(更改行時使用$ file-> current()),然后再調用seek($ rowKey)到達上一行,然后下一個文件將輸出第一行兩次,第二行將丟失。 第三行以及之后的所有內容都被很好地打印了。 這是使用以下代碼實現的問題:

$path = "file.1.txt";
$whileCounter = 0;
while ($path != null) {
  $file = new SplFileObject($path);
  $file->setFlags(SplFileObject::READ_CSV);
  $file->setCsvControl("\t");
  $path = null;
  foreach ($file as $rowKey => $row) {
    if ($whileCounter > 0) {
      var_dump($row);
      echo "<br>";
    }
    $file->seek($rowKey + 1);
    if ($file->valid()) {
      $file->seek($rowKey);
    } else {
      var_dump($row);
      echo "<br>";
      $path = "file.2.txt";
    }
  }
  $whileCounter++;
}

如果您應用自定義.csv文件(至少有五個非空行)而不是file.1.txt和file.2.txt,則您將看到第二個和第三個輸出是相同的(第二個和第三個輸出是第一和第二個) file.2.txt的“第二”行)。 這有什么問題嗎?

那沒有。 Foreach在$file變量上使用了一個迭代器,即使更改了$file的值,該迭代器仍然有效。

或者,換句話說, foreach將繼續查看$file的先前內容,無論之后如何處理。 這是因為$file實際上不是SplFileObject ,而是對其的引用,並且該引用由foreach

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM