3

I have a class with a private constructor, to prevent direct instantiation.

class MyClass {

    private static $instance;

    private function __construct() {

    }

    public static function getInstance() {
        if (isset(self::$instance)) {
            return self::$instance;
        } else {
            $c = __CLASS__;
            self::$instance = new $c;
            return self::$instance;
        }
    }

}

I extend it

class ExtendedClass Extends MyClass {
    //cannot touch parent::$instance, since it's private, so must overwrite
    private static $instance;
    //calling parent::getInstance() would instantiate the parent, 
    //not the extension, so must overwrite that too
    public static function getInstance() {
        if (isset(self::$instance)) {
            return self::$instance;
        } else {
            $c = __CLASS__;
            self::$instance = new $c;
            return self::$instance;
        }
    }
}

When I call

$myInstance=ExtendedClass::getInstance();

In PHP 5.4.5 I get

PHP Fatal error: Call to private MyClass::__construct() from context 'ExtendedClass'

But In PHP 5.1.6, everything works as expected

What is happening here?

Also: I did not write MyClass, I don't have the ability to make the constructor protected, If I did that would solve the problem, but I can't.

2
  • Why don't you make your parent constructor protected rather than private? Commented Apr 3, 2014 at 20:08
  • I can't! I didn't actually write MyClass, I don't have the ability to modify it. Commented Apr 3, 2014 at 20:35

1 Answer 1

3
+250

It is the bug. You could fix your code like this (PHP > PHP5.3):

class MyClass {

    private static $instance;

    private function __construct() {

    }

    static function getInstance() {
        if (isset(self::$instance)) {
            return self::$instance;
        } else {
            self::$instance = new static();
            return self::$instance;
        }
    }

}


class ExtendedClass Extends MyClass {
}
Sign up to request clarification or add additional context in comments.

2 Comments

Way to find documentation of the bug! Excellent! Thanks!
Static analyzers will complain about this code with Unsafe usage of new static() (IMHO, rightfully so, because new static() can lead to hard to spot bugs). To fix this, you should also mark the private constructor with final, so that it cannot be overridden.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.