我有一个 url 数组,我想传递给一个函数,我将使用 cron 作业每 2 分钟只传递其中的 10 个,我将这个数组的最后一个传递的索引存储在数据库中,问题是我不知道当最后一个传递的元素是数组中的最后一个元素时如何传递前 2 个元素, 让我用代码解释一下:
$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()
工作正常,但是当$last_passed_index
4
时,我只得到数组中的最后一个元素,当它5
(最后一个索引)时,我得到一个空数组。
我想做的是,当4
获取最后一个元素和第一个元素时,以及当5
哪个是最后一个元素的索引以获取数组中的前 2 个元素时。
我对php不太好,有什么建议我应该怎么做而不是创建一个函数来检查索引?
一个有趣的解决方案是利用 SPL 迭代器。 无限迭代器是要使用的一个。
在此示例中,您从最后一个数组元素开始并迭代两次:
$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/"
}
半聪明的技巧:用array_merge
复制URL列表,这样你就可以重复两次。然后从该双精度列表中进行选择。这将允许您从结尾选择与开头重叠的切片。
$start_from = ($last_passed_index + 1) % count($sites_to_pass);
$to_pass = array_slice(array_merge($sites, $sites), $start_from, $sites_to_pass, true);
添加 % count($sites_to_pass)
会使$start_from
一旦超过数组的末尾,就会从 0 重新开始。这可以让您永远循环。
有点脏,但像这样:
$to_pass = $start_from == 5 ? array($sites[5], $sites[0]) : array_slice($sites, $start_from, $sites_to_pass, true);