PHP 日本大会 2024

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) 的回复。

我认为,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
8 年前
注意 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