0

i read a csv file from a server and i loop through it using foreach:

if (file_exists($fi)){
        $lines = file($fi);
        foreach ($lines as $line_num => $line) {
           // do something ....

           if ($addline){
              $newline = "123;Las Vegas;982";
              array_push($lines, $newline);
           }
        }
}

While looping through the array i decide to add a new element to the end of the array and i like to process this element in the same foreach-loop.

In the other post you only have mulitple pointer to the same array. I dont want to run the array twice.

Mike
  • 693
  • 1
  • 13
  • 31
  • 2
    Foreach makes a _copy_ of the array, and works on that. You would _see_ the new element in `$lines`, if you dumped that variable directly after you added the new item - but the foreach loop itself will not _iterate_ over that new item. Your phrasing is a bit unclear here, on whether you just need to add new elements to the array - so that they will be available for whatever else you need to do _after_ the loop - or if you wanted the loop itself to iterate over those new items as well. The former will work, the latter won't. – CBroe Mar 02 '22 at 12:54
  • Your immediate question of _whether_ this will work could have been answered in about 2 minutes by testing it yourself. For the subtleties of _why_ it behaves as it does, see the linked duplicate. – IMSoP Mar 02 '22 at 13:11
  • The file you are reading is in CSV format, do not use file(), use fgetcsv(). file() will split the file by each newline that it finds, even newlines that appear within a field (i.e. within quotations). – Reynadan Mar 02 '22 at 13:14
  • @CBroe The need to duplicate the array was largely eliminated in PHP 7, because a single array can now have multiple iterators pointing at it, rather than incrementing a single "internal array pointer". See Nikita's incredibly detailed answer on the linked duplicate. – IMSoP Mar 02 '22 at 13:14
  • I like to iterate over the newly added element in the loop aswell – Mike Mar 02 '22 at 13:21
  • @IMSoP _"a single array can now have multiple iterators pointing at it"_ - that's good to know, but for the specific problem here I don't see what that would help; I don't think they want _multiple_ iterators here, but process the existing and the newly added items within one and the same loop. And I don't think _that_ is possible ...? – CBroe Mar 02 '22 at 13:32
  • Yes i like to process the newly added item in the same loop! – Mike Mar 02 '22 at 13:45
  • @CBroe You're right. If I understand Nikita's description correctly, what now happens is that _the call to `array_push`_ will trigger the duplication. The `foreach` loop acts like an extra variable pointing to the original array, so copy-on-write kicks in like it would if you wrote `$temp = $lines; array_push($lines, 'whatever');` So, the end result is the same: the modification happens to a different array in memory from what's being looped over. – IMSoP Mar 02 '22 at 14:15
  • You could do it by simply replacing the foreach with a while loop though (assuming, you don't need the original array "intact" after the loop) - `while($line = array_shift($lines)) { ... }` Anything you add to `$lines` inside that loop, _will_ be processed once all previous items have been processed. If you really need the line counter as well, you'll have to keep your own counter and do a $counter++ in the loop. Difference illustrated with a basic example here, https://3v4l.org/M0379 – CBroe Mar 03 '22 at 08:01

0 Answers0