SplQueue 类

(PHP 5 >= 5.3.0,PHP 7,PHP 8)

简介

SplQueue 类通过将迭代器模式设置为 **SplDoublyLinkedList::IT_MODE_FIFO** 提供了使用双向链表实现的队列的主要功能。

类概要

class SplQueue extends SplDoublyLinkedList {
/* 继承的常量 */
/* 方法 */
public dequeue(): mixed
public enqueue(mixed $value): void
/* 继承的方法 */
public SplDoublyLinkedList::add(int $index, mixed $value): void
}

示例

示例 #1 SplQueue 示例

<?php
$q
= new SplQueue();
$q[] = 1;
$q[] = 2;
$q[] = 3;
foreach (
$q as $elem) {
echo
$elem."\n";
}
?>

上面的示例将输出

1
2
3

示例 #2 使用 SplQueue 高效地处理任务

<?php
$q
= new SplQueue();
$q->setIteratorMode(SplQueue::IT_MODE_DELETE);
// ... 在队列中入队一些任务 ...
// 处理它们
foreach ($q as $task) {
// ... 处理 $task ...
// 在队列中添加新的任务
$q[] = $newTask;
// ...
}
?>

目录

添加备注

用户贡献备注 6 个备注

Manu Manjunath
10 年前
SplQueue 继承自 SplDoublyLinkedList。因此,SplQueue 的对象支持 push() 和 pop() 方法。但是请注意,如果对 SplQueue 对象使用 push() 和 pop() 方法,它的行为类似于堆栈而不是队列。

例如

$q = new SplQueue();
$q->push(1);
$q->push(2);
$q->push(3);
$q->pop();
print_r($q);

上面的代码返回

SplQueue 对象
(
[flags:SplDoublyLinkedList:private] => 4
[dllist:SplDoublyLinkedList:private] => 数组
(
[0] => 1
[1] => 2
)
)

请注意,3 被弹出,而不是 1。

因此,请确保您仅对 SplQueue 对象使用 enqueue() 和 dequeue() 方法,而不是 push() 和 pop() 方法。
MrStonedOne
9 年前
您可以使用 shift/unshift 和 push/pop 来分别进行出队/入队和入队/出队。对于那些使用套接字的应用程序来说非常方便,您可能在尝试之前不知道无法发送数据。

例如,这是一个用于应用程序的函数,该函数将在 socket_write 指示它没有写入提供的数据的全部内容的情况下,从队列中删除剩余的数据。

<?php
function processSendQueue($socket, $sendQueue) {
while (!
$sendQueue->isEmpty()) {
//shift() 等同于 dequeue()
$senditem = $sendQueue->shift();

//返回写入的字节数。
$rtn = socket_write($socket, $senditem);
if (
$rtn === false) {
$sendQueue->unshift($senditem);
throw new
exception("发送错误: " . socket_last_error($socket));
return;
}
if (
$rtn < strlen($senditem) {
$sendQueue->unshift(substr($senditem, $rtn);
break;
}
}
}
?>
lincoln dot du dot j at gmail dot com
7 年前
<?php

$queue
= new SplQueue();
$queue->enqueue('A');
$queue->enqueue('B');
$queue->enqueue('C');

$queue->rewind();
while(
$queue->valid()){
echo
$queue->current(),"\n";
$queue->next();
}

print_r($queue);
$queue->dequeue(); //删除第一个
print_r($queue);

?>
输出

A
B
C
SplQueue 对象
(
[flags:SplDoublyLinkedList:private] => 4
[dllist:SplDoublyLinkedList:private] => 数组
(
[0] => A
[1] => B
[2] => C
)

)
SplQueue 对象
(
[flags:SplDoublyLinkedList:private] => 4
[dllist:SplDoublyLinkedList:private] => 数组
(
[0] => B
[1] => C
)

)
booleantype at ya dot ru
3 年前
对 Manu Manjunath 帖子 (#114336) 的回复。

IMO,pop() 按预期工作。

主要有两组方法

1) pop() & push() 继承自 SplDoublyLinkedList,可以应用于 SplStack 以及 SplQueue(即“无面”)。这不是关于堆栈或队列;只是关于删除/添加列表末尾的元素;

2) shift() & unshift() 也是如此:它只是关于在列表开头添加一个元素,而我们是在 SplStack 上使用它还是 SplQueue 上使用它并不重要。

所以,是的,$q->pop(); 将从 SplQueue $q 中删除*最后一个*元素。

但 enqueue() & dequeue() *是关于* SplQueue 的。FIFO 原则由这些方法实现,这些方法是*专门*为了队列目的而实现的
- enqueue() 将一个元素添加到队列的末尾,是“无面”push() 的别名(FI...);
- dequeue() 从队列的开头删除元素,是“无面”shift() 的别名(...FO)。

如果你想从*队列*中删除*下一个*元素,请使用 dequeue()。
如果你想从列表中删除*最后一个*元素(无论它是队列还是堆栈),请使用 pop()。
Stingus
7 年前
注意 SplQueue::valid() 在队列有节点时不会返回 true。请改用 isEmpty()

$queue = new SplQueue();
$queue->enqueue('A');
$queue->enqueue('B');
$queue->enqueue('C');
var_dump($queue->valid()); // false
var_dump(!$queue->isEmpty()); // true
mostefa dot medjahed dot pro at gmail dot com
3 年前
如前所述,SplQueue 对象上的 push () 和 pop () 方法的行为类似于堆栈而不是队列。

知道 enqueue () 和 dequeue () 方法分别是 push () 和 shift () 方法的别名,我们也可以使用 SplQueue :: push () 和 SplQueue :: shift () 来实现与 SplQueue :: enqueue 和 SplQueue :: dequeue 相同的目的。
To Top