0

I've created Singleton class below but how do I know that only one instance has been created. How do I test it? Also, is there any difference between self::$instance = new FileProcessor() and self::$instance = new static() or which one should I use?

Thanks

CLASS

class FileProcessor
{
    protected static $instance = null;

    public static function get_instance()
    {
        if (self::$instance === null)
        {
            self::$instance = new FileProcessor();
            //self::$instance = new static();
        }

        return self::$instance;
    }
}

$obj_1 = FileProcessor::get_instance();
echo '<pre>'; print_r($obj_1);

$obj_2 = FileProcessor::get_instance();
echo '<pre>'; print_r($obj_2);

OUTPUT

FileProcessor Object
(
)
FileProcessor Object
(
)
BentCoder
  • 12,257
  • 22
  • 93
  • 165

3 Answers3

2

Ideally you wouldn't be using a singleton pattern to begin with. Instead you dependency inject an instance of FileProcessor to everything that needs it. That means all the places in your app which need FileProcessor don't "get it themselves", rather they receive it from a higher authority. Instead of:

function foo() {
    $fp = FileProcessor::getInstance();
    ...
}

you do:

function foo(FileProcessor $fp) {
    ...
}

This allows you to instantiate exactly one FileProcessor and inject it everywhere it's needed. This gives you full control over its use. You can couple this with a registry/dependency injection container pattern to make managing dependencies easier.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • Thanks for opening my eyes. How do I change my example in order to use your second function? – BentCoder Apr 11 '14 at 09:27
  • All of the code you show deals with instantiating a singleton. You basically delete all that. Then you just leave one `$obj_1 = new FileProcessor;` and pass that `$obj_1` to every function and class that needs it. – deceze Apr 11 '14 at 09:32
  • BTW, you may also be interested in this: [How Not To Kill Your Testability Using Statics](http://kunststube.net/static/) – deceze Apr 11 '14 at 09:42
  • Is it like this then?`class FileProcessor { //Whatever } $obj = new FileProcessor; function foo($obj) { echo '
    '; var_dump($obj);
    }
    
    foo($obj);`
    – BentCoder Apr 11 '14 at 10:25
  • Exactly. I'd also add the type hint `FileProcessor $obj` to the `function foo`, as shown in my answer. – deceze Apr 11 '14 at 10:27
  • I removed it to see what happens and nothing changed but if you think it is best practice or has advantage then I'll use it. – BentCoder Apr 11 '14 at 10:32
1

You can compare the result by using === operator. In your case: $obj_1 === $obj_2 will return true if both objects refer to the same instance. More info here: http://www.php.net/manual/en/language.oop5.object-comparison.php. And also here is a good explanation of using new static() : New self vs. new static

Community
  • 1
  • 1
Ulan Murzatayev
  • 870
  • 5
  • 15
1

var_dump function allows you to view the contents of the object. This code demonstrates that the objects are really the same:

<?php
class FileProcessor
{
    protected static $instance = null;
    private $arr = array();

    public static function get_instance()
    {
        if (self::$instance === null)
        {
            self::$instance = new FileProcessor();
            //self::$instance = new static();
        }

        return self::$instance;
    }

    public function set($key, $value)
    {
    $this->arr[$key] = $value;
    }
}

$obj_1 = FileProcessor::get_instance();
$obj_1->set('this-is-key', 'this-is-value');
echo '<pre>'; var_dump($obj_1);

$obj_2 = FileProcessor::get_instance();
echo '<pre>'; var_dump($obj_2);
user3383116
  • 392
  • 1
  • 7