实例作为静态类属性

9

在PHP中,是否可以将类的实例声明为属性?

基本上我想要实现的是:

abstract class ClassA() 
{
  static $property = new ClassB();
}

好的,我知道我不能这样做,但除了总是像这样做有没有其他解决方法:

if (!isset(ClassA::$property)) ClassA::$property = new ClassB();

这个问题之前已经被问过多次了。属性不能用运行时依赖信息进行初始化。在构造函数中设置实例,或者在Getter中进行延迟加载。 - Gordon
1
是的,我知道我可以在构造函数中设置它,但在我的情况下,我需要一个静态类。不过还是谢谢你的努力 :) - paudam
单例模式是一种软件设计模式,用于限制类的实例化次数为一个。这通常是通过隐藏构造函数并提供一个静态方法来访问单个实例来实现的。单例模式被广泛应用于计算机科学中,特别是在创建对象时需要避免多个实例对系统资源的竞争的情况下。 - Hannes
@Paulius,你也可以在构造函数中设置静态属性,所以我不明白为什么要加上“但是”。 - Gordon
3个回答

21

你可以使用类似单例模式的实现:

<?php
class ClassA {

    private static $instance;

    public static function getInstance() {

        if (!isset(self::$instance)) {
            self::$instance = new ClassB();
        }

        return self::$instance;
    }
}
?>

那么你可以使用以下方式引用该实例:

ClassA::getInstance()->someClassBMethod();

5
我更倾向于将其命名为 getB() 而不是 getInstance。 - Gordon

4

0

这篇文章有些年头了,但我最近遇到了一个问题,我有一个基类。

class GeneralObject
{

    protected static $_instance;

    public static function getInstance()
    {
        $class = get_called_class();

        if(!isset(self::$_instance))
        {
            self::$_instance = new $class;
        }

        return self::$_instance;
    }
}

那有一个子类

class Master extends GeneralObject 
{

}

还有另一个子类

class Customer extends Master 
{

}

但是当我尝试调用时

$master = Master::getInstance();
$customer = Customer::getInstance();

那么$master将会如预期一样是Master,但$customer将会是Master,因为PHP使用GeneralObject::$_instance来处理MasterCustomer

我能够实现想要的唯一方法是将GeneralObject::$_instance更改为array并调整getInstance()方法。

class GeneralObject
{

    protected static $_instance = array();

    public static function getInstance()
    {
        $class = get_called_class();

        if(!isset(self::$_instance[$class]))
        {
            self::$_instance[$class] = new $class;
        }

        return self::$_instance[$class];
    }
}

我希望这对其他人有所帮助。花了我几个小时来调试问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接