3

I have the following four PHP files:

1. Singleton.php

<?php

class Singleton {
    private static $instance = null;

    protected function __clone() {}
    private function __construct() {}

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

?>

2. Debugger.php

<?php

interface Debugger {
    public function debug($message);
}

?>

3. DebuggerEcho.php

<?php
require_once 'Singleton.php';
require_once 'Debugger.php';

class DebuggerEcho extends Singleton implements Debugger {
    public function debug($message) {
        echo $message . PHP_EOL;
    }
}

?>

4. TestSingleton.php

<?php
require_once 'DebuggerEcho.php';

$debugger = DebuggerEcho::getInstance();
$debugger->debug('Hello world');

?>

Problem is, when I call line $debugger->debug('Hello world'). I want to keep this structure but avoid this (classical) message:

Call to undefined method Singleton::debug() in TestSingleton.php.

What is going wrong? Thank you for help.

RePRO
  • 67
  • 1
  • 9

1 Answers1

2

The expression new self creates an object of the class where it's contained; here Singleton. To create an object of the class you use for the call you can use new static instead (assuming you are using PHP 5.3 or later):

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

See also: What does new self(); mean in PHP?

Not that this implementation of Singleton is not really reusable because it supports only one instance. For example you couldn't use this Singleton class as a base class for both database connections and loggers: it can only hold one or the other.

Community
  • 1
  • 1
Joni
  • 108,737
  • 14
  • 143
  • 193
  • This works like a charm - fix it, but we must use - new static. Older version of PHP (x < 5.3) would not be able to solve this problem, so? – RePRO Jun 08 '13 at 18:32
  • For older versions of PHP 5 there's a workaround using `ReflectionClass`, you can find it in comments here: http://www.php.net/manual/en/language.oop5.late-static-bindings.php – Joni Jun 08 '13 at 18:40
  • We can summarize that the problem is in the Late Static Bindings. Thank you again for clear answers. – RePRO Jun 08 '13 at 18:42