[php] Reverse order of foreach list items

I would like to reverse the order of this code's list items. Basically it's a set of years going from oldest to recent and I am trying to reverse that output.

<?php
    $j=1;     
    foreach ( $skills_nav as $skill ) {
        $a = '<li><a href="#" data-filter=".'.$skill->slug.'">';
        $a .= $skill->name;                 
        $a .= '</a></li>';
        echo $a;
        echo "\n";
        $j++;
    }
?>  

This question is related to php

The answer is


Walking Backwards

If you're looking for a purely PHP solution, you can also simply count backwards through the list, access it front-to-back:

$accounts = Array(
  '@jonathansampson',
  '@f12devtools',
  '@ieanswers'
);

$index = count($accounts);

while($index) {
  echo sprintf("<li>%s</li>", $accounts[--$index]);
}

The above sets $index to the total number of elements, and then begins accessing them back-to-front, reducing the index value for the next iteration.

Reversing the Array

You could also leverage the array_reverse function to invert the values of your array, allowing you to access them in reverse order:

$accounts = Array(
  '@jonathansampson',
  '@f12devtools',
  '@ieanswers'
);

foreach ( array_reverse($accounts) as $account ) {
  echo sprintf("<li>%s</li>", $account);
}

Or you could use the array_reverse function.


If your array is populated through an SQL Query consider reversing the result in MySQL, ie :

SELECT * FROM model_input order by creation_date desc

If you don't mind destroying the array (or a temp copy of it) you can do:

$stack = array("orange", "banana", "apple", "raspberry");

while ($fruit = array_pop($stack)){
    echo $fruit . "\n<br>"; 
}

produces:

raspberry 
apple 
banana 
orange 

I think this solution reads cleaner than fiddling with an index and you are less likely to introduce index handling mistakes, but the problem with it is that your code will likely take slightly longer to run if you have to create a temporary copy of the array first. Fiddling with an index is likely to run faster, and it may also come in handy if you actually need to reference the index, as in:

$stack = array("orange", "banana", "apple", "raspberry");
$index = count($stack) - 1;
while($index > -1){
    echo $stack[$index] ." is in position ". $index . "\n<br>";
    $index--;
} 

But as you can see, you have to be very careful with the index...


You can use usort function to create own sorting rules


Assuming you just need to reverse an indexed array (not associative or multidimensional) a simple for loop would suffice:

$fruits = ['bananas', 'apples', 'pears'];
for($i = count($fruits)-1; $i >= 0; $i--) {
    echo $fruits[$i] . '<br>';
} 

<?php
    $j=1; 


      array_reverse($skills_nav);   


    foreach ( $skills_nav as $skill ) {
        $a = '<li><a href="#" data-filter=".'.$skill->slug.'">';
        $a .= $skill->name;                 
        $a .= '</a></li>';
        echo $a;
        echo "\n";
        $j++;
    }
?> 

array_reverse() does not alter the source array, but returns a new array. (See array_reverse().) So you either need to store the new array first or just use function within the declaration of your for loop.

<?php 
    $input = array('a', 'b', 'c');
    foreach (array_reverse($input) as $value) {
        echo $value."\n";
    }
?>

The output will be:

c
b
a

So, to address to OP, the code becomes:

<?php
    $j=1;     
    foreach ( array_reverse($skills_nav) as $skill ) {
        $a = '<li><a href="#" data-filter=".'.$skill->slug.'">';
        $a .= $skill->name;                 
        $a .= '</a></li>';
        echo $a;
        echo "\n";
        $j++;
}

Lastly, I'm going to guess that the $j was either a counter used in an initial attempt to get a reverse walk of $skills_nav, or a way to count the $skills_nav array. If the former, it should be removed now that you have the correct solution. If the latter, it can be replaced, outside of the loop, with a $j = count($skills_nav).