2024 年日本 PHP 研討會

SplQueue 類別

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

簡介

SplQueue 類別提供佇列的主要功能,它使用雙向鏈結串列實作,並將迭代器模式設定為 SplDoublyLinkedList::IT_MODE_FIFO

類別概要

class SplQueue extends SplDoublyLinkedList {
/* 繼承的常數 */
/* 方法 */
公開 dequeue(): 混合
公開 enqueue(混合 $value):
/* 繼承方法 */
公開 SplDoublyLinkedList::add(整數 $index, 混合 $value):
}

範例

範例 #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 來執行 dequeue/undequeue 和 queue/unqueue。對於使用 sockets 的應用程式來說非常方便,因為您可能在嘗試傳送資料之前不知道無法傳送資料。

例如,這是一個應用程式函式,如果 socket_write 指示它沒有寫入提供的資料的全部內容,它將取消佇列剩餘的資料。

<?php
函數 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() 將元素新增到佇列的尾端,它是 "faceless" push() (FI...) 的別名;
- dequeue() 從佇列的開頭移除元素,它是 "faceless" 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