如何迭代类的实例

时间:2012-02-16 20:39:36

标签: php oop

有没有办法迭代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似乎既不是作为类中的静态方法,也不是作为类之外的函数。目前我必须创建一个球名称数组,并使用它来查找该类的每个实例。谢谢!

3 个答案:

答案 0 :(得分:1)

  

目前,我必须制作一个球名称数组,并使用它来查找该类的每个实例。

这是实现您想要做的事情的正确方法。稍微更多的OO方法将使用某种类型的集合类(例如,BallPit,如Daff的答案中所述),但原理是相同的。

还有其他方法,例如创建一种混合multiton(与传统的多重不同,它不会限制可以创建的实例数量,但只能创建新的实例通过拥有类的静态方法来管理创建的实例数组。

但是,如果您(或可能有一天会)为您的应用程序使用自动化测试,它将给您带来巨大的麻烦。

答案 1 :(得分:0)

嗯,我很确定你必须以某种方式跟踪某个地方的实际实例(而不仅仅是他们的名字)。例如。在类 BallPit 或包含球列表的主脚本中。这也是您遍历列表并获取每个实例CSS的地方。

答案 2 :(得分: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中的实例方法中。