2011-07-20 81 views
1

我有個問題與實現Iterator接口 下面是代碼:類實現迭代循環

class User_Model_Users implements Iterator, Countable 
{ 

    protected $_count; 
    protected $_gateway; 
    protected $_resultSet; 

    public function __construct($results, $gateway) 
    { 
     $this->setGateway($gateway); 
     $this->_resultSet = $results; 
    } 

    public function setGateway(User_Model_UserGateway $gateway) 
    { 
     $this->_gateway = $gateway; 
     return $this; 
    } 

    public function getGateway() 
    { 
     return $this->_gateway; 
    } 

    public function count() 
    { 
     if (null === $this->_count) { 
      $this->_count = count($this->_resultSet); 
     } 
     return $this->_count; 
    } 

    public function current() 
    { 
     if ($this->_resultSet instanceof Iterator) { 
      $key = $this->_resultSet->key(); 
     } else { 
      $key = key($this->_resultSet); 
     } 
     $result = $this->_resultSet [$key]; 
     if (!$result instanceof User_Model_User) { 
      $gateway = $this->getGateway(); 
      $result = $gateway->createUser($result); 
      $this->_resultSet [$key] = $result; 
     } 
     return $result; 
    } 

    public function key() 
    { 
     return key($this->_resultSet); 
    } 

    public function next() 
    { 
     return next($this->_resultSet); 
    } 

    public function rewind() 
    { 
     return reset($this->_resultSet); 
    } 

    public function valid() 
    { 
     return (bool) $this->current(); 
    } 

} 

其$結果我提供Zend_Db_Table_Rowset但它可以是也其他物體或陣列。 我該如何解決這個問題,以便我在foreach循環中工作? 我沒有收到任何錯誤,因爲它是一個無限循環。

+1

「還可以是其它的對象或數組」 - 在此情況下的示例腳本+數據和預期的結果將是很好。 – VolkerK

+0

現在它不適用於Zend_Db_Table_Rowset。我想解決這個案例 – greg606

+0

你的具體問題是什麼?你認爲需要解決什麼?你得到哪個錯誤? 「它不起作用」並沒有說什麼不行。 – hakre

回答

1

胡亂猜測(還沒有真正開始鑽研代碼):

由於您實現有效的()是

public function valid() 
{ 
    return (bool) $this->current(); 
} 

你應該確保電流()時,有沒有返回false更多的元素

public function current() 
{ 
    if ($this->_resultSet instanceof Iterator) { 
     $key = $this->_resultSet->key(); 
    } else { 
     $key = key($this->_resultSet); 
    } 

    if (is_null($key) ) { // could also be is_null($key)||false===$key, not sure... 
     return false; 
    } 

    $result = $this->_resultSet[$key]; 
    if (!$result instanceof User_Model_User) { 
     $gateway = $this->getGateway(); 
     $result = $gateway->createUser($result); 
     $this->_resultSet[$key] = $result; 
    } 
    return $result; 
} 

,並順便說一句:您的功能鍵()不執行instanceof Iterator情況類似電流()一樣。


測試腳本:

<?php 
class User_Model_Users implements Iterator, Countable 
{ 
    protected $_count; 
    protected $_gateway; 
    protected $_resultSet; 

    public function __construct($results, $gateway) 
    { 
     $this->setGateway($gateway); 
     $this->_resultSet = $results; 
     $this->_count = null; 
    } 

    public function setGateway(User_Model_UserGateway $gateway) 
    { 
     $this->_gateway = $gateway; 
     return $this; 
    } 

    public function getGateway() 
    { 
     return $this->_gateway; 
    } 

    public function count() 
    { 
     if (is_null($this->_count)) { 
      $this->_count = count($this->_resultSet); 
     } 
     return $this->_count; 
    } 

    public function current() 
    { 
     if ($this->_resultSet instanceof Iterator) { 
      $key = $this->_resultSet->key(); 
     } else { 
      $key = key($this->_resultSet); 
     } 
     if (is_null($key)) { 
      return false; 
     } 

     $result = $this->_resultSet[$key]; 
     if (!$result instanceof User_Model_User) { 
      $gateway = $this->getGateway(); 
      $result = $gateway->createUser($result); 
      $this->_resultSet[$key] = $result; 
     } 
     return $result; 
    } 

    public function key() 
    { 
     return key($this->_resultSet); 
    } 

    public function next() 
    { 
     return next($this->_resultSet); 
    } 

    public function rewind() 
    { 
     return reset($this->_resultSet); 
    } 

    public function valid() 
    { 
     return (bool) $this->current(); 
    } 
} 

class User_Model_User { 
    protected $x, $y; 

    public function __construct($x, $y) { 
     $this->x = $x; 
     $this->y = $y; 
    } 
} 

class User_Model_UserGateway { 
    protected $id; 
    public function __construct() { 
     $this->id = time(); 
    } 

    public function createUser($x) { 
     echo "User_Model_UserGateway::createUser($x)\n"; 
     return new User_Model_User($x, $this->id); 
    } 
} 

$a = array('a', 'b', 'c', 'd'); 
$users = new User_Model_Users($a, new User_Model_UserGateway); 
foreach($users as $u) { 
    print_r($u); 
} 

打印

User_Model_UserGateway::createUser(a) 
User_Model_User Object 
(
    [x:protected] => a 
    [y:protected] => 1311167311 
) 
User_Model_UserGateway::createUser(b) 
User_Model_User Object 
(
    [x:protected] => b 
    [y:protected] => 1311167311 
) 
User_Model_UserGateway::createUser(c) 
User_Model_User Object 
(
    [x:protected] => c 
    [y:protected] => 1311167311 
) 
User_Model_UserGateway::createUser(d) 
User_Model_User Object 
(
    [x:protected] => d 
    [y:protected] => 1311167311 
) 
+0

不幸的是,這不起作用。 – greg606

+0

@ greg606然後,我真的需要一個示例腳本,因爲我的簡單測試腳本說不然;-) – VolkerK

+0

請看看:https://github.com/greg606/zf-core – greg606