转到更新以阅读现在的实际问题。 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而不是编写新的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
语句来解决这个问题。递归似乎是合适的解决方案,但如果有一种方法可以动态地更改循环中的对象,我宁愿这个解决方案。
更新 如#34;旧问题"所有使用过的文件(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,您将看到第二个和第三个输出相同(第二个和第三个输出)是第一个和第二个&#34;行的file.2.txt)。这可能有什么问题?
答案 0 :(得分:2)
没有。 Foreach在$file
变量上使用迭代器,即使您更改了$file
的值,迭代器仍然有效。
或者,换句话说,foreach
将继续查看$file
的先前内容,无论您之后使用它做什么。这是因为$file
实际上不是SplFileObject
,而是对它的引用,而引用由foreach
使用。