如何循环一个数组,当我们到达终点时重新开始?

I have an array of urls that I want to do pass to a function, I'll be using a cron job to pass only 2 of them every 10 minutes, I'm storing the last passed index of this array in a database, the problem is I don't know how to pass the first 2 elements when the last passed element is the last one in the array, let me explain with the code:

$sites = array(
    'http://www.example.com/',
    'http://www.example1.com/',
    'http://www.example2.com/',
    'http://www.example3.com/',
    'http://www.example4.com/',
    'http://www.example5.com/'
);

// the number of urls to pass to the function
// Edit: I forgot to say that this number might change later
$sites_to_pass = 2;

// this value is supposed to be stored when we finish processing the urls
$last_passed_index = 2;

// this is the next element's index to slice from
$start_from = $last_passed_index + 1;

// I also want to preserve the keys to keep track of the last passed index
$to_pass = array_slice($sites, $start_from, $sites_to_pass, true);

array_slice() is working fine, but when the $last_passed_index is 4 I only get the last element in the array, and when it's 5 (the last index) I get an empty array.

What I want to do is when it's 4 to get the last element and the first element, and when it's 5 which is the last element's index to get the first 2 elements in the array.

I'm not so good with php, any suggestions what should I do instead of creating a function to check the indexes ?

One interesting solution is to make use of the SPL Iterators. The InfiniteIterator is the one to use.

In this example, you start with the last array element and iterate twice:

$sites = array(
    'http://www.example0.com/',
    'http://www.example1.com/',
    'http://www.example2.com/',
    'http://www.example3.com/',
    'http://www.example4.com/',
    'http://www.example5.com/'
);

$result = array();
$infinite = new InfiniteIterator(new ArrayIterator($sites));

// this value is supposed to be stored when we finish processing the urls
$last_passed_index = 5;

// this is the next element's index to slice from
$start_from = $last_passed_index + 1;

foreach (new LimitIterator($infinite, $start_from, 2) as $site) {
    $result[] = $site;
}

var_dump($result);

// output
array(2) {
  [0]=>
  string(24) "http://www.example0.com/"
  [1]=>
  string(24) "http://www.example1.com/"
}

Little dirty, but something like:

$to_pass = $start_from == 5 ? array($sites[5], $sites[0]) : array_slice($sites, $start_from, $sites_to_pass, true);

Semi-clever trick: duplicate the URL list with array_merge so you have it repeated twice. Then select from that doubled list. That'll let you select slices from the end that overlap the beginning.

$start_from = ($last_passed_index + 1) % count($sites_to_pass);
$to_pass    = array_slice(array_merge($sites, $sites), $start_from, $sites_to_pass, true);

Adding % count($sites_to_pass) makes $start_from start back over at 0 once it exceeds the end of the array. This lets you loop forever.