John Aston
John Aston

Reputation: 127

PHP class extends Singleton pattern

class singleton:

class Singleton
{
    private static $_myself;

    private function __construct(){}

    public static function getInstance()
    {
        if(!isset(self::$_myself))
        {
            $obj = __CLASS__;
            self::$_myself = new $obj;
        }
        return self::$_myself;
    }
}

my class:

 class MyApp extends Singleton
    {
        public function show()
        {
            echo 'show';
        }
    }
    MyApp::getInstance()->show();

but not working, this error: Call to undefined method Singleton::show() somebody can help me?

Upvotes: 2

Views: 1426

Answers (3)

PascalKleindienst
PascalKleindienst

Reputation: 168

self returns the actual class instance (Singleton in this case), so there is no method show. But you could use static instead of self (Differences) and change $_myself from private to protected so it is accessible in child classes.

class Singleton
{
    protected static $_myself;

    private function __construct(){}

    public static function getInstance()
    {
        if(!isset(static::$_myself))
        {
            static::$_myself = new static;
        }
        return static::$_myself;
    }
}

Upvotes: 2

Daniel W.
Daniel W.

Reputation: 32260

The problem is in

$obj = __CLASS__;
self::$_myself = new $obj;

You create a new instance of the class Singleton, not of the class MyApp, so the method is not available.

Now h2ooooooo was faster with his answer than I edited, see his answer regarding what to put instead of __CLASS__.

Upvotes: -1

h2ooooooo
h2ooooooo

Reputation: 39522

Because you're returning a Singleton class (as you can see by your error), but should be returning a MyApp class. You can do this by using the late static binding method get_called_class() introduced in PHP 5.3:

public static function getInstance()
{
    if(!isset(self::$_myself))
    {
        //__CLASS__ = Singleton | get_called_class() = MyApp
        $obj = get_called_class(); 
        self::$_myself = new $obj;
    }
    return self::$_myself;
}

Upvotes: 3

Related Questions