9

Is it possible to declare an instance of a class as a property in PHP?

Basically what I want to achieve is:

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

Well, I know I can't do that, but is there any workaround beside always doing something like this:

if (!isset(ClassA::$property)) ClassA::$property = new ClassB();
paudam
  • 103
  • 1
  • 1
  • 4
  • [This has been asked multiple times before.](http://stackoverflow.com/questions/5984360/php-property-as-object) [Properties cannot be initialized with runtime dependent information.](http://php.net/manual/en/language.oop5.properties.php) Set the instance in the Ctor. Or lazy load it in a Getter. – Gordon Feb 06 '12 at 11:14
  • 1
    Yes, I know I can set it in a constructor, but in my case I need a class to be static. Thanks for an effort though :) – paudam Feb 06 '12 at 11:23
  • http://en.wikipedia.org/wiki/Singleton_pattern ? – Hannes Feb 06 '12 at 11:25
  • @Paulius you can also set static properties in the ctor, so I dont see a reason for the "but". – Gordon Feb 06 '12 at 12:00

3 Answers3

21

you can use a singleton like implementation:

<?php
class ClassA {

    private static $instance;

    public static function getInstance() {

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

        return self::$instance;
    }
}
?>

then you can reference the instance with:

ClassA::getInstance()->someClassBMethod();
Zuul
  • 16,217
  • 6
  • 61
  • 88
Yaron U.
  • 7,681
  • 3
  • 31
  • 45
4

An alternative solution, a static constructor, is something along the lines of

<?php
abstract class ClassA {
    static $property;
    public static function init() {
        self::$property = new ClassB();
    }
} ClassA::init();
?>

Please note that the class doesn't have to be abstract for this to work.

See also How to initialize static variables and https://stackoverflow.com/a/3313137/118153.

Community
  • 1
  • 1
Iiridayn
  • 1,747
  • 21
  • 43
0

This is a few years old, but I just ran into a issue where I have a base class

class GeneralObject
{

    protected static $_instance;

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

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

        return self::$_instance;
    }
}

That has a Child Class

class Master extends GeneralObject 
{

}

And another Child class

class Customer extends Master 
{

}

But when I try to call

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

then $master will be Master as expected, but $customer will be Master because php uses the GeneralObject::$_instance for both Master and Customer

The only way I could achieve what I want was to change the GeneralObject::$_instance to be an array and adjust the getInstance() method.

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];
    }
}

I hope this helps someone else out there. Took me a few hours to debug what was going on.

James W
  • 11
  • 3