2013-02-03 111 views
0

我已经从SPL迭代器扩展和实现了。
但是,如果我想使用它,我应该在foreach上使用它。
我想在一个while像这样使用它:PHP迭代器像mysql迭代器?

$news = new testClass(); 

while($row = $news) 
    echo $row["name"]; 

这将创建一个无限循环!
但与foreach,它工作正常!

这里是我最想去类:

class testClass implements \Iterator 

哪里错了吗?

+2

使用'while'圈更是一个C风格的迭代器比你想的迭代器。你需要实现['Iterator'方法](http://php.net/manual/en/class.iterator.php),然后应该使用foreach循环。 –

+1

您是否试图迭代'$ news'对象中的公共属性? – halfer

回答

1

对于这种类型的“标准”问题,使用SPL类的拳头,bravo。我经常看到没有经验的/拙劣的开发人员(甚至是那些根本没有想到的好开发人员)在这些情况下重新发明轮子。

您错过了一些关于iterator接口实施的非常重要的细节。

有关更多信息,请参阅PHP:Iterator - Manual以及参考实施。

首先,您需要实现,rewind, current, key, next, and valid函数。参考实现是这样的:

class myIterator implements Iterator { 
    private $position = 0; 
    private $array = array(
     "firstelement", 
     "secondelement", 
     "lastelement", 
    ); 

    public function __construct() { 
     $this->position = 0; 
    } 

    function rewind() { 
     var_dump(__METHOD__); 
     $this->position = 0; 
    } 

    function current() { 
     var_dump(__METHOD__); 
     return $this->array[$this->position]; 
    } 

    function key() { 
     var_dump(__METHOD__); 
     return $this->position; 
    } 

    function next() { 
     var_dump(__METHOD__); 
     ++$this->position; 
    } 

    function valid() { 
     var_dump(__METHOD__); 
     return isset($this->array[$this->position]); 
     } 
    } 
) 

而对于遍历实现代码如下所示:

$it = new myIterator; 

foreach($it as $key => $value) { 
    var_dump($key, $value); 
    echo "\n"; 
} 
+0

+1!感谢您的回答。我已经有这种风格。如果你回到我的问题上,我说这是我班的顶尖! –

+0

我发现了这一点,但它并没有告诉我你已经实现了必要的功能。然后,您的问题的答案将覆盖示例代码的第二部分(使用foreach而不是for)。 – DavidDraughn

1

foreach是语言结构,通过所有元素进行迭代。 while执行代码块直到给定的条件为真。为了使它工作,你必须使用你自己的函数来检查有效密钥并返回当前元素。

+0

+1为逻辑 –

0

最后,我创建了一个简单的例子:

<?php 

/** 
* @author Soroush Khosravi 
* @copyright 2013 
*/ 
class _Iterator 
{ 
    private $array; 

    public function setArray(array $data) 
    { 
     $this->array = $data; 
    } 

    public function reader() 
    { 
     if (is_null($this->array)) 
      return false; 

     $elem = array_shift($this->array); 
     if (count ($this->array) > 0) 
      return $elem; 
     return false; 
    } 
} 

Class child extends _Iterator 
{ 
    function execute() 
    { 
     $this->setArray(array(1,2,3,4,5,6)); 
     return $this; 
    } 
} 
$obj = new child; 
$obj = $obj->execute(); 
while($row = $obj->reader()) 
    echo $row; 

?> 
+0

无需回答自己的问题。并且请记住,这会导致数组中的任何虚假值失效(例如,尝试在3和4之间设置0),所以更好地使用'foreach'。 –

+0

@ dev-null-dweller我不记得我问过'foreach'!我正在寻找这种形式,现在这是我的答案,我认为这是真的:) –

+1

我只是说,你可能有这个构造的一些价值的麻烦,就这样。 –