612

The question is simple. I have a foreach loop in my code:

foreach($array as $element) {
    //code
}

In this loop, I want to react differently when we are in first or last iteration.

How to do this?

Hasen
  • 11,710
  • 23
  • 77
  • 135
mehdi
  • 9,262
  • 11
  • 35
  • 35
  • You should update the question with PHP. Javascript has forEach loop too. Viewers can get a misleading answer. – Maidul Mar 12 '21 at 16:52
  • @Maidul True, in google it's not clear at all that it's about PHP so I added the word "PHP" to the title for clarity. – Hasen Apr 16 '22 at 05:36

21 Answers21

1262

If you prefer a solution that does not require the initialization of the counter outside the loop, then you can compare the current iteration key against the function that tells you the last / first key of the array.

PHP 7.3 and newer:

foreach ($array as $key => $element) {
    if ($key === array_key_first($array)) {
        echo 'FIRST ELEMENT!';
    }

    if ($key === array_key_last($array)) {
        echo 'LAST ELEMENT!';
    }
}

PHP 7.2 and older:

PHP 7.2 is already EOL (end of life), so this is here just for historic reference. Avoid using.

foreach ($array as $key => $element) {
    reset($array);
    if ($key === key($array)) {
        echo 'FIRST ELEMENT!';
    }

    end($array);
    if ($key === key($array)) {
        echo 'LAST ELEMENT!';
    }
}
Rok Kralj
  • 46,826
  • 10
  • 71
  • 80
  • 15
    This should bubble all the way to the top because it is the right answer. Another advantage of these functions over using array_shift and array_pop is that the arrays are left intact, in case they are needed at a later point. +1 for sharing knowledge just for the sake of it. – Awemo Apr 30 '12 at 17:09
  • 1
    This should bubble all the way to the top as it is the cleanest one! – user776686 Jun 07 '12 at 11:21
  • 13
    this is definitely the best way if you're wanting to keep your code clean. I was about to upvote it, but now I'm not convinced the functional overhead of those array methods is worth it. If we're just talking about the last element then that is `end()` + `key()` over every iteration of the loop - if it's both then that's 4 methods being called every time. Granted, those would be very lightweight operations and are probably just pointer lookups, but then the docs do go on to specify that `reset()` and `end()` *modify* the array's internal pointer - so is it quicker than a counter? possibly not. – pospi Jun 20 '12 at 09:01
  • 2
    If you are worried about that minimal optimisation, you can cache key() into variable, before the scope of for loop. But as I have said, don't worry about that. – Rok Kralj Jun 20 '12 at 20:22
  • 19
    I don't think you should issue reset($array) inside a foreach. From the official documentation (www.php.net/foreach): "As foreach relies on the internal array pointer changing it within the loop may lead to unexpected behavior." And reset does precisely that (www.php.net/reset): "Set the internal pointer of an array to its first element" – Gonçalo Queirós Jan 15 '13 at 12:17
  • 12
    @GonçaloQueirós: It works. Foreach works on a copy of array. However, if you are still concerned, feel free to move the `reset()` call before the foreach and cache the result in `$first`. – Rok Kralj Jan 17 '13 at 08:35
  • wait, so what happens if I compare `$element` with `$array[0]` ? – Chibueze Opata Mar 12 '13 at 11:28
  • 1
    That works, if you have a sequential array. For example, this it would not work, if you had `$array = array('a' => 1, 'b' => 2)`, then `$array[0]` would return NULL and issue a notice. – Rok Kralj Mar 12 '13 at 17:29
  • As Gonsalo said, Note that you can't use pointer here. ie - `foreach($array as $key=>&$value)`. It will reset the iteration counter in this case. Use standard `foreach($array as $key=>$value)` – Mladen Janjetovic May 16 '13 at 10:03
  • 1
    Agreed. Great, simple & elegant answer. I hate stupid counters in loops, so this really changes my POV on associative array iteration. Fantastic! – Giacomo1968 Aug 08 '13 at 18:14
  • Keep in mind that the updated (last) solution added will copy the whole array and use twice memory. Use isLast(& $array, $key) to prevent this. – dompie Feb 17 '14 at 07:32
  • Note that with this last update (using `last(&$array, $key)`), you will actually set the pointer of the original array to the last element. Without the `&`, that won't happen because it's a copy of the original array. I would remove the `&`. The function would have a higher memory usage, but it might prevent some unexpected behaviour. – dbroeks Mar 07 '14 at 08:41
  • 4
    I don't get why you all upvote this. Just use a boolean for "first" thats just better than everything else. The accepted answer is the way to go without running into "special cases". – OderWat Oct 08 '15 at 12:02
  • This answer is valid if you use simple arrays you have total control over, but if you're using objects from a platform/framework, that you hesitate to really mess with then Gumbo's answer fits better – DM8 Feb 16 '18 at 15:55
  • 1 liner: if (end($array) && $key === key($array)){ – Andrew Dec 08 '18 at 18:17
  • And why not take `end($array);` and `key($array)` out of the loop? – kodfire Nov 20 '22 at 10:11
514

You could use a counter:

$i = 0;
$len = count($array);
foreach ($array as $item) {
    if ($i == 0) {
        // first
    } else if ($i == $len - 1) {
        // last
    }
    // …
    $i++;
}
Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • 29
    I do not think downvoting should take place here as this is also working correctly and is still not so rubbish as using `array_shift` and `array_pop`. Though this is the solution I'd came up if I had to implement such a thing, I'd stick with the **Rok Kralj's** answer now on. – shadyyx May 15 '13 at 14:27
  • 17
    If I need a counter, then I prefer to use FOR loop instead of FOREACH. – rkawano Nov 14 '14 at 22:53
  • 17
    If you use `$i = 1`, you don't have to worry about `$len - 1`, just use `$len`. – aksu Apr 03 '15 at 07:32
  • @Deji How is point three wrong? It's way cleaner to use a list instead of a div for each individual item. –  Dec 22 '15 at 12:59
  • 2
    @Twan How is point #3 right? Or relevant at all to this question since it involves HTML? This is a PHP question, clearly... and when it comes to mark-up semantics, it's down to a much deeper facts than "a proper blahblah is always better than blahblah (this is not even my opinion, it's pure fact)" – Deji Dec 23 '15 at 11:59
  • @Deji I think the question originally contained quite a bit of HTML ([before Rok edited it to make it cleaner](http://stackoverflow.com/revisions/1070244/4) - '14). – Cullub Feb 02 '16 at 20:13
  • 2
    @rkawano but you can't get the **named key** if you use FOR loop – Fahmi Sep 03 '16 at 19:03
  • Why not use a regular for loop for these occasions? If you need to reference where you are in the loop, that seems to be the most logical way. A counter is just mimicking this – Kellen Stuart Jul 19 '17 at 17:05
  • @KolobCanyon - the reason is that a `for` loop won't work with associative array. – But those new buttons though.. Dec 28 '18 at 18:55
  • Really Rok Kralj's answer is what most of us were looking for. But the requirement for PHP 7.3 means to use array_key_first and array_key_last means that this is really the method we should be using to create portable code. Thanks. – hiburn8 Feb 07 '19 at 12:45
  • You don´t need declare the `$i` variable, just use the foreach index: `foreach ($array as $index => $item) {` then in the rest of the code replace all `$i` with `$index`. – Fellipe Sanches Dec 04 '19 at 13:40
  • 1
    Then why not to use a for loop? – Musa Haidari Jun 05 '20 at 11:07
137

To find the last item, I find this piece of code works every time:

foreach( $items as $item ) {
    if( !next( $items ) ) {
        echo 'Last Item';
    }
}
Benoit Esnard
  • 2,017
  • 2
  • 24
  • 32
Yojance
  • 1,549
  • 1
  • 9
  • 8
  • 2
    This has too few upvotes, is there any drawback to using this? – Kevin Kuyl Apr 19 '16 at 22:19
  • 11
    [`next`: **Warning** This function may return Boolean **`FALSE`**, but may also return a non-Boolean value which evaluates to **`FALSE`**. Please read the section on Booleans for more information. Use the `===` operator for testing the return value of this function.](http://php.net/manual/en/function.next.php) – Pang Jul 25 '16 at 01:54
  • 2
    @Kevin Kuyl - As mentioned by Pang above, if the array contains an item that PHP evaluates as false (i.e. 0, "", null) this method will have unexpected results. I've amended the code to use === – Eric Kigathi Sep 01 '16 at 17:44
  • 2
    So I assume to be certain you replace (!next($items)) with (next($items)===FALSE). I'm no php expert so just wanted to check. – PedroKTFC Dec 10 '16 at 08:51
  • 4
    this is mostly very awesome but to clarify to problem others are pointing out it will invariably fail with an array like `[true,true,false,true]`. But personally I will be using this anytime I am dealing with an array that doesn't contain boolean `false`. – But those new buttons though.. Jan 10 '17 at 02:05
  • 1
    I get really weird behavior with this `next()` check in a foreach loop, this is a really tricky piece of code. Firstly I get *two* "Last Item" notices, and secondly, when `next()` is called multiple times (e.g. in two separate conditions), extremely weird stuff happens. Seems like `next()` and `foreach()` each have their own array pointer. Tested on PHP 5.5.20. – mvds Oct 16 '17 at 02:17
  • 10
    `next()` should _NEVER_ be used inside a foreach loop. It messes up the internal array pointer. Check out the documentation for more info. – Ian Hazzard Jan 17 '18 at 19:59
  • Kudos for this answer. So simple and has thorough support for earlier versions of PHP. –  Oct 02 '19 at 08:42
  • [To still use next() and properly check if the end of the array has been reached, verify that the key() is NULL.](https://www.php.net/manual/en/function.next.php) – Frederick Zhang Jan 29 '20 at 03:04
103

A more simplified version of the above and presuming you're not using custom indexes...

$len = count($array);
foreach ($array as $index => $item) {
    if ($index == 0) {
        // first
    } else if ($index == $len - 1) {
        // last
    }
}

Version 2 - Because I have come to loathe using the else unless necessary.

$len = count($array);
foreach ($array as $index => $item) {
    if ($index == 0) {
        // first
        // do something
        continue;
    }

    if ($index == $len - 1) {
        // last
        // do something
        continue;
    }
}
Hayden
  • 2,082
  • 1
  • 14
  • 18
  • 10
    This works for objects too. The other solutions work for arrays only. – Yasen Jan 30 '14 at 06:41
  • 1
    This is best answer for me but should be condensed, no point declaring length outside the foreach loop: if ($index == count($array)-1){ ... } – Andrew Oct 22 '15 at 14:14
  • 4
    @Andrew that way you keep counting the elements of the array, for every iteration. – pcarvalho Jul 13 '16 at 16:29
  • 2
    @peteroak Yes actually it would technically hurts performance, and depending what your counting or how many loops could be significant. So disregard my comment :D – Andrew Jul 13 '16 at 17:44
  • 4
    @peteroak @Andrew The total number of elements in an array is stored as a property internally, so there would not be any performance hits by doing `if ($index == count($array) - 1)`. See [here](https://nikic.github.io/2012/03/28/Understanding-PHPs-internal-array-implementation.html). – Katrina Aug 26 '16 at 17:35
  • @GreeKatrina Nice find! So, since performance would not necessarily be an issue the rest is just up to personal preference. – Hayden Aug 26 '16 at 17:58
43

You could remove the first and last elements off the array and process them separately.

Like this:

<?php
$array = something();
$first = array_shift($array);
$last = array_pop($array);

// do something with $first
foreach ($array as $item) {
 // do something with $item
}
// do something with $last
?>

Removing all the formatting to CSS instead of inline tags would improve your code and speed up load time.

You could also avoid mixing HTML with php logic whenever possible.

Your page could be made a lot more readable and maintainable by separating things like this:

<?php
function create_menu($params) {
  //retrieve menu items 
  //get collection 
  $collection = get('xxcollection') ;
  foreach($collection as $c) show_collection($c);
}

function show_subcat($val) {
  ?>
    <div class="sub_node" style="display:none">
      <img src="../images/dtree/join.gif" align="absmiddle" style="padding-left:2px;" />
      <a id="'.$val['xsubcatid'].'" href="javascript:void(0)" onclick="getProduct(this , event)" class="sub_node_links"  >
        <?php echo $val['xsubcatname']; ?>
      </a>
    </div>
  <?php
}

function show_cat($item) {
  ?>
    <div class="node" >
      <img src="../images/dtree/plus.gif" align="absmiddle" class="node_item" id="plus" />
      <img src="../images/dtree/folder.gif" align="absmiddle" id="folder">
      <?php echo $item['xcatname']; ?>
      <?php 
        $subcat = get_where('xxsubcategory' , array('xcatid'=>$item['xcatid'])) ;
        foreach($subcat as $val) show_subcat($val);
      ?>
    </div>
  <?php
}

function show_collection($c) {
  ?>
    <div class="parent" style="direction:rtl">
      <img src="../images/dtree/minus.gif" align="absmiddle" class="parent_item" id="minus" />
      <img src="../images/dtree/base.gif" align="absmiddle" id="base">
      <?php echo $c['xcollectionname']; ?>
      <?php
        //get categories 
        $cat = get_where('xxcategory' , array('xcollectionid'=>$c['xcollectionid']));
        foreach($cat as $item) show_cat($item);
      ?>
    </div>
  <?php
}
?>
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Carlos Lima
  • 4,162
  • 29
  • 32
  • I like the idea of **last** (removing the last element from the array), so that I can generate the last element differently without checking at every loop. – massimoi Jan 10 '21 at 18:03
21

An attempt to find the first would be:

$first = true; 
foreach ( $obj as $value )
{
  if ( $first )
  {
    // do something
    $first = false; //in order not to get into the if statement for the next loops
  }
  else
  {
    // do something else for all loops except the first
  }
}
sstauross
  • 2,602
  • 2
  • 30
  • 50
  • 3
    Please edit your answer to add an explanation of how your code works and how it solves the OP's problem. Many SO posters are newbies and will not understand the code you have posted. – i alarmed alien Oct 27 '14 at 15:06
  • 4
    This answer doesn't say how to determine if you're in the last iteration of the loop. It is, however, a valid attempt at an answer, and shouldn't be flagged as not an answer. If you don't like it, you should down vote it, not flag it. – ArtOfWarfare Oct 27 '14 at 15:12
  • It's clear , in the first iteration he will enter the first condition and then changes it value to false , and this way it will only get into first iteration once. – Mohamed23gharbi Aug 10 '15 at 16:32
21

Simply this works!

// Set the array pointer to the last key
end($array);
// Store the last key
$lastkey = key($array);  
foreach($array as $key => $element) {
    ....do array stuff
    if ($lastkey === key($array))
        echo 'THE LAST ELEMENT! '.$array[$lastkey];
}

Thank you @billynoah for your sorting out the end issue.

Sydwell
  • 4,954
  • 1
  • 33
  • 36
13

1: Why not use a simple for statement? Assuming you're using a real array and not an Iterator you could easily check whether the counter variable is 0 or one less than the whole number of elements. In my opinion this is the most clean and understandable solution...

$array = array( ... );

$count = count( $array );

for ( $i = 0; $i < $count; $i++ )
{

    $current = $array[ $i ];

    if ( $i == 0 )
    {

        // process first element

    }

    if ( $i == $count - 1 )
    {

        // process last element

    }

}

2: You should consider using Nested Sets to store your tree structure. Additionally you can improve the whole thing by using recursive functions.

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
okoman
  • 5,529
  • 11
  • 41
  • 45
  • If you're going to use a `for` you can loop from `1` to `n-1` and take the `if`s out of the body. No point checking them repeatedly. – mpen Jan 28 '16 at 16:29
9

Best answer:

$arr = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

foreach ($arr as $a) {

// This is the line that does the checking
if (!each($arr)) echo "End!\n";

echo $a."\n";

}
Ivan
  • 2,316
  • 2
  • 24
  • 22
  • 2
    This fails when you have only one element in the array. – Memochipan May 11 '14 at 19:00
  • 4
    It is fast and easy as long as you can be sure there are always more than one lement in the array (as Memochipan said). So it's not a failsafe solution for me - no 'best answer'. – Seika85 May 14 '14 at 07:44
  • 5
    **each() will be DEPRECATED as of PHP 7.2.0**. Please also see http://php.net/manual/en/function.each.php – Flow Jul 31 '17 at 05:55
8

The most efficient answer from @morg, unlike foreach, only works for proper arrays, not hash map objects. This answer avoids the overhead of a conditional statement for every iteration of the loop, as in most of these answers (including the accepted answer) by specifically handling the first and last element, and looping over the middle elements.

The array_keys function can be used to make the efficient answer work like foreach:

$keys = array_keys($arr);
$numItems = count($keys);
$i=0;

$firstItem=$arr[$keys[0]];

# Special handling of the first item goes here

$i++;
while($i<$numItems-1){
    $item=$arr[$keys[$i]];
    # Handling of regular items
    $i++;
}

$lastItem=$arr[$keys[$i]];

# Special handling of the last item goes here

$i++;

I haven't done benchmarking on this, but no logic has been added to the loop, which is were the biggest hit to performance happens, so I'd suspect that the benchmarks provided with the efficient answer are pretty close.

If you wanted to functionalize this kind of thing, I've taken a swing at such an iterateList function here. Although, you might want to benchmark the gist code if you're super concerned about efficiency. I'm not sure how much overhead all the function invocation introduces.

Community
  • 1
  • 1
TheMadDeveloper
  • 1,587
  • 15
  • 28
6

For SQL query generating scripts, or anything that does a different action for the first or last elements, it is much faster (almost twice as fast) to avoid using unneccessary variable checks.

The current accepted solution uses a loop and a check within the loop that will be made every_single_iteration, the correct (fast) way to do this is the following :

$numItems = count($arr);
$i=0;
$firstitem=$arr[0];
$i++;
while($i<$numItems-1){
    $some_item=$arr[$i];
    $i++;
}
$last_item=$arr[$i];
$i++;

A little homemade benchmark showed the following:

test1: 100000 runs of model morg

time: 1869.3430423737 milliseconds

test2: 100000 runs of model if last

time: 3235.6359958649 milliseconds

And it's thus quite clear that the check costs a lot, and of course it gets even worse the more variable checks you add ;)

Morg.
  • 89
  • 1
  • 1
  • Your code only works if you can be sure to have to have incrementing integer keys. `$arr = array('one' => "1 1 1", 4 => 'Four', 1 => 'One'); $numItems = count($arr); $i=0; $firstitem=$arr[0]; echo $i . ': ' . $firstitem . ", "; $i++; while($i<$numItems-1){ $some_item=$arr[$i]; echo $i . ': ' . $some_item . ", "; $i++; } $last_item=$arr[$i]; echo $i . ': ' . $last_item . ", "; $i++;` will output: `0: , 1: One, 2: ,` – Seika85 May 14 '14 at 07:51
  • casting a hash map to an array is undefinable behaviour, the "Object" `array()` made is `{'one':"1 1 1",0:"",1:"One",2:"",3:"",4:"Four"}` but the empty elements are ignored with count, you are counting the number of defined "things"!! BOUNTY SACRIFICE INCOMING! This answer deserves bounty, but if @Morg. gone, it is pointless. I would give bounty to a person who probably wont use SO again! If he comes back and improves his answer, he deserves the bounty! – mjz19910 Jun 30 '16 at 10:05
  • As @mjz19910 notes, hash maps and arrays are not interchangeable. However, you can get the properties of the hash with the `array_keys` function, which you *can* treat like an array. See [my "improved" answer](http://stackoverflow.com/a/38155703/4496866). – TheMadDeveloper Jul 02 '16 at 01:43
  • That is what I use for query: `$querySet = ""; foreach ($fieldSet as $key=>$value) { $value = $db->dbLink->quote($value); $querySet .= "$key = $value, "; } $querySet = substr_replace($querySet, "", -2); $queryString = "UPDATE users SET $querySet WHERE user_ID = '$user_ID'";` – Rovshan Mamedov Feb 05 '18 at 14:40
5

With Keys and Values this works as well:

foreach ($array as $key => $value) {
    if ($value === end($array)) {
        echo "LAST ELEMENT!";
    }
}
Benibr
  • 962
  • 10
  • 12
5

Using a Boolean variable is still the most reliable, even if you want to check the first appearance of a $value (I found it more useful in my situation and in many situations), such like this:

$is_first = true;

foreach( $array as $value ) {
    switch ( $value ) {
        case 'match':
            echo 'appeared';

            if ( $is_first ) {
                echo 'first appearance';
                $is_first = false;
            }

            break;
        }
    }

    if( !next( $array ) ) {
        echo 'last value';
    }
}

Then how about !next( $array ) to find the last $value which will return true if there's no next() value to iterate.

And I prefer to use a for loop instead of foreach if I were going to use a counter, like this:

$len = count( $array );
for ( $i = 0; $i < $len; $i++ ) {
    $value = $array[$i];
    if ($i === 0) {
        // first
    } elseif ( $i === $len - 1 ) {
        // last
    }
    // …
    $i++;
}
4

I came across this thread when I have the same problem. I only need to get the first element then I re-analyze my code until this came up to my mind.

$firstElement = true;

foreach ($reportData->result() as $row) 
{
       if($firstElement) { echo "first element"; $firstElement=false; }
       // Other lines of codes here
}

The above codes are great and complete but if you only need just the first element then you may try this code.

paul
  • 96
  • 2
3

Using reset($array) and end($array)

<?php

    $arrays = [1,2,3,4,5];

    $first  = reset($arrays);
    $last   = end($arrays);    

    foreach( $arrays as $array )
    {

        if ( $first == $array )
        {
            echo "<li>{$array} first</li>";
        }
        else if ( $last == $array )
        {
            echo "<li>{$array} last</li>";
        }
        else
        {
            echo "<li>{$array}</li>";
        }                

    }

Demo repl.it

antelove
  • 3,216
  • 26
  • 20
2

Not sure if it still necessary. But the following solution should work with iterators and does not require count.

<?php

foreach_first_last(array(), function ($key, $value, $step, $first, $last) {
    echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});

foreach_first_last(array('aa'), function ($key, $value, $step, $first, $last) {
    echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
echo PHP_EOL;

foreach_first_last(array('aa', 'bb', 'cc'), function ($key, $value, $step, $first, $last) {
    echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
echo PHP_EOL;

function foreach_first_last($array, $cb)
{
    $next = false;
    $current = false;
    reset($array);
    for ($step = 0; true; ++$step) {
        $current = $next;
        $next = each($array);
        $last = ($next === false || $next === null);
        if ($step > 0) {
            $first = $step == 1;
            list ($key, $value) = $current;
            if (call_user_func($cb, $key, $value, $step, $first, $last) === false) {
                break;
            }
        }
        if ($last) {
            break;
        }
    }
}
vbarbarosh
  • 3,502
  • 4
  • 33
  • 43
1

You can use an anonymous function, too:

$indexOfLastElement = count($array) - 1;
array_walk($array, function($element, $index) use ($indexOfLastElement) {
    // do something
    if (0 === $index) {
        // first element‘s treatment
    }
    if ($indexOfLastElement === $index) {
        // last not least
    }
});

Three more things should be mentioned:

  • If your array isn‘t indexed strictly (numerically) you must pipe your array through array_values first.
  • If you need to modify the $element you have to pass it by reference (&$element).
  • Any variables from outside the anonymous function you need inside, you‘ll have to list them next to $indexOfLastElement inside the use construct, again by reference if needed.
undko
  • 927
  • 8
  • 15
0

You can use the counter and array length.

    $array = array(1,2,3,4);

    $i = 0;
    $len = count($array);
    foreach ($array as $item) {
        if ($i === 0) {
            // first
        } else if ($i === $len - 1) {
            // last
        }
        // …
        $i++;
    }
Jesus Erwin Suarez
  • 1,571
  • 16
  • 17
0
foreach ($arquivos as $key => $item) {
   reset($arquivos);
   // FIRST AHEAD
   if ($key === key($arquivos) || $key !== end(array_keys($arquivos)))
       $pdf->cat(null, null, $key);

   // LAST
   if ($key === end(array_keys($arquivos))) {
       $pdf->cat(null, null, $key)
           ->execute();
   }
}
0

The simplest way would be

$array = [9,5,6,4,7,8];

$current_iteration = 0;

foreach($array as $item){
  if( 0 === $current_iteration ){
    echo 'this is the first item: ' . $item;
  }

  if( (count($array) - 1) === $current_iteration){
    echo 'this is the last item: ' . $item;
  }

  $current_iteration++;
}
Reza Khan
  • 86
  • 3
-3

Try this:

function children( &$parents, $parent, $selected ){
  if ($parents[$parent]){
    $list = '<ul>';
    $counter = count($parents[$parent]);
    $class = array('first');
    foreach ($parents[$parent] as $child){
      if ($child['id'] == $selected)  $class[] = 'active';
      if (!--$counter) $class[] = 'last';
      $list .= '<li class="' . implode(' ', $class) . '"><div><a href="]?id=' . $child['id'] . '" alt="' . $child['name'] . '">' . $child['name'] . '</a></div></li>';
      $class = array();
      $list .= children($parents, $child['id'], $selected);
    }
    $list .= '</ul>';
    return $list;
  }
}
$output .= children( $parents, 0, $p_industry_id);
bool.dev
  • 17,508
  • 5
  • 69
  • 93