2012-02-16 67 views
1

有沒有辦法在PHP中遍歷一個類的所有實例?我可以通過在創建靜態變量時對它們進行計數來手動執行它,但我更願意能夠製作適用於每個類實例的靜態方法。如何迭代類的實例

例如,假設我有一個名爲Ball的類,它可以通過構造函數爲每個球創建一個唯一的ID和一組特徵。 Ball類有一個方法,通過名爲getCSSrule()的方法爲特定的球生成CSS。我想創建一個名爲getCSS()的靜態方法,該方法將爲每個現有球調用getCSSrule(),爲當前存在的所有球寫出整個CSS塊。然後,不要爲每個球調用$ obj-> getCSSrule(),而只需調用一次Ball :: getCSS()。

public static function getCSS(){ 
    $css; 
    foreach(Ball as $obj){ 
    $css += $obj->getCSSrule(); 
    } 
    return $css; 
} 

該foreach似乎並不能作爲類中的靜態方法或作爲類之外的函數。目前,我必須創建一個球的名稱數組,並使用它來查找每個類的實例。謝謝!

+1

我很難理解你想要做什麼。請澄清問題。也許刪除所有的實現細節,只是說明你的設置/場景以及你想要的輸出/目標是什麼。 – Gordon 2012-02-16 20:41:53

+1

似乎與[這個問題](http://stackoverflow.com/questions/475569/get-all-instances-of-a-class-in-php) – parkker007 2012-02-16 20:55:45

+0

好找parkker007,我錯過了那一個。 – 2012-02-19 01:07:30

回答

0

嗯,我很確定你必須在某處以某種方式跟蹤實際的實例(不只是他們的名字)。例如。在一個類BallPit或您的主腳本包含一個球的列表。這也是你遍歷列表並獲取每個實例CSS的地方。

1

目前我必須製作一個球的名稱數組,並用它來查找每個類的實例。

這是實現您正在嘗試做的正確方法。稍微多一點的面向對象方法會利用某種類的集合類(例如,如Daff的回答中所述的BallPit),但原理是相同的。

還有其他的方法,例如創建一種混合(與傳統的多層不同,它不會限制可以創建的實例的數量,但是隻能通過靜態創建新的實例擁有類的方法,它將管理已創建的實例的數組)。

但是,如果您(或可能有一天會)爲您的應用程序使用自動化測試,將會給您帶來很大的麻煩。

0

的字面解釋下列給出的實施細則會是這樣的

class Ball 
{ 
    protected static $balls = array(); 
    protected $cssRule; 

    public function __construct($cssRule) 
    { 
     self::$balls[] = $this; 
     $this->cssRule = $cssRule; 
    } 
    public static function getCss() 
    { 
     $css = ''; 
     foreach (self::$balls as $ball) { 
      $css .= $ball->getCssRule(); 
     } 
     return $css; 
    } 
    public function getCssRule() 
    { 
     return $this->cssRule; 
    } 
} 

換句話說,你可以收集創建的實例的靜態屬性。然後,您可以按照您的問題要求做什麼,例如(demo

new Ball('foo'); 
new Ball('bar'); 
new Ball('baz'); 
echo Ball::getCSS(); 

然後打印foobarbaz。這是否是一個好方法是一個不同的問題。我更喜歡另一種方法是這樣的:

class Balls implements IteratorAggregate 
{ 
    protected $balls; 

    public function __construct() 
    { 
     $this->balls = new SplObjectStorage; 
    } 
    public function attach(Ball $ball) 
    { 
     $this->balls->attach($ball); 
    } 
    public function detach(Ball $ball) 
    { 
     $this->balls->detach($ball); 
    } 
    public function getIterator() 
    { 
     return clone($this->balls); 
    } 
    public function create($cssRule) 
    { 
     $ball = new Ball($cssRule); 
     $this->attach($ball); 
     return $ball; 
    } 
} 

然後,您可以做

$balls = new Balls; 
$balls->create('foo'); 
$balls->create('bar'); 
$balls->create('baz'); 

創造新Ball情況下,它會自動地存儲在Balls。並且因爲BallsIteratorAggregate,所以您可以簡單地迭代foreach的所有實例,例如,

$css = ''; 
foreach($balls as $ball) { 
    $css .= $ball->getCssRule(); 
} 
echo $css; 

當然,您也可以將該代碼移動到Balls的實例方法中。