SplQueue的无限循环

时间:2015-02-01 13:38:25

标签: php queue spl

我需要一个队列,我在队列中添加对象(先进先出)。 另外,我跟踪哈希映射中没有重复的对象。

<?php

$test = new \SplQueue();
$done = array();

// Put 'test a' in queue
$test->enqueue('test a');

// While we have objects in the queue...
while ($test->valid()) {
    // Echo the current object
    $current = $test->current();
    echo $current, PHP_EOL;

    // Remove the current object and add it to "done"
    $test->dequeue();
    $done[$current] = 1;

    // Add more to queue
    $new = array('test a', 'test b', 'test c');
    foreach ($new as $newObject) {
        if (! isset($done[$newObject])) {
            $test->enqueue($newObject);
        }
    }
}

在PHP codepad中,我没有得到任何结果。 有什么问题?

更新:过了一会儿我得到输出:

test a 
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /code/NIPg42 on line 25
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /code/NIPg42 on line 25

我为已经完成的对象出列并测试,为什么这是一个无限循环?

第25行是$test->enqueue($newObject);

1 个答案:

答案 0 :(得分:2)

对我来说,使用SplQueue更简单(也更自然),使用两个基本方法 only enqueue将一个项目放在队列的末尾,并且dequeue提取您必须从队列开头处理的项目。这意味着使用current结果取代dequeue

$current = $test->dequeue();
$done[$current] = 1;
var_dump($current); // or any other processing

尝试将空列表出列会导致错误,您必须先检查它。所以你的代码变得类似于:

$test = new \SplQueue();
$done = array();

// Put 'test a' in queue
$test->enqueue('test a');

// While we have objects in the queue...
while (!$test->isEmpty()) {
    $item = $test->dequeue();
    $done[$item] = 1;
    var_dump($item); 

    // Add more to queue
    $new = array('test a', 'test b', 'test c');
    foreach ($new as $newObject) {
        if (! isset($done[$newObject])) {
            $test->enqueue($newObject);

// without this line, `test c` will be enqueued twice.
            $done[$newObject] = 1; 
        }
    }
}

Demo。如您所见,此处还有另一个变化:在执行enqueue之前设置哈希值。如果你确实想要制作一个HashQueue(一种),我建议你自己创建一个类(扩展或使用SplQueue);密钥将伴随每个enqueue操作,并对相应的哈希检查/添加。