![](/img/trans.png)
[英]How to remove the extra line when using PHP SplFileObject and READ_CSV flag?
[英]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.