views:

59

answers:

1

Hi all,

I have a simple question. I use a singleton which implements an abstract class. Is it possible to put the getInstance() Method and the variable $_instance in the abstract class instead of the concrete one I want to create?

Here's my code:

<?php
class Command_Log extends Command_Abstract {
    private static $_instance=null;

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

    protected function realExecute() {
    }

    protected function realSimulate($fileHandle) {
    }

}

and

<?php

abstract class Command_Abstract implements Command_Interface {
    protected $_data=array();
    //private static $_instance=null;
    protected $_isExecuted=false;
    protected $_execute=false;


    public function enableExecute() {
        $this->_execute=true;
        return $this;
    }

    protected function __construct() {

    }
    protected function __clone() {}


    public function addData($data) {

        array_push($this->_data,$data);
        return $this;
    }

    abstract protected function realExecute();

    abstract protected function realSimulate($fileHandle);

    public function execute() {
        if(!$this->_isExecuted && $this->_execute) {
            $this->_isExecuted = true;
            $this->realExecute();
        }
    }

    public function simulate() {
        $exitSystem = false;
        if(!$this->_isExecuted && $this->_execute) {
            $this->_isExecuted = true;
                $exitSystem = $this->realSimulate($fh);
            }
        }
        return $exitSystem;
    }

}

I have many implementations of the the commands, so I don't want redundant code everywhere in my implementations. Is it possible to put these two things in the abstract class, if yes please tell me how.

If not please explain it to me why it isnt possbile. Or if I need to change something to do it, anyhow.

regards

+2  A: 

YES WE CAN!

I have a class called Singleton that is abstract... and many classes that extends that Singleton class... this is the code:

abstract class Singleton {

    private static $instances = array();

    final private function __construct($_params) {
        $class = get_called_class();
        if (array_key_exists($class, self::$instances))
            throw new Exception('An instance of '. $calledClass .' already exists !');

        //static::initialize(); //In PHP 5.3
        $this->initialize($_params); 
    }
    final private function __clone() { }

    abstract protected function initialize();

    public static function getInstance($_params=array()) {
        $class = get_called_class();
        if (array_key_exists($class, self::$instances) === false){
            self::$instances[$class] = new $class($_params);
        } 
        return self::$instances[$class];
    }
}

and (for example) the class DBConnection that extends from Singleton

class DBConnection extends Singleton{

    private $connexion_pdo=null;

    protected function initialize(){
             //connect to the DB
        $this->connexion_pdo = blablalba;
    }
}

although there are some problems in php 5.2.. specially with the function get_called_class() and the static::initialize()

You could also check the php site for patterns... there are lots of contributions for the singleton

Good Luck

pleasedontbelong
+1, although when you say "there are some problems in php 5.2", what you mean is "this is impossible in PHP 5.2"! The new feature, for anyone who doesn't know, is [late static binding](http://php.net/manual/en/language.oop5.late-static-bindings.php) and will be very useful in all kinds of ways in making PHP's OOP support far more flexible.
lonesomeday
actually the code is made for 5.2.. i used a function that simulates the function get_called_class() http://www.septuro.com/2009/07/php-5-2-late-static-binding-get_called_class-and-self-new-self/ and instead of using the static binding with self::initialize i use the $this->initialize (that's why i commented that line on the Singleton class) Im not really sure if it's correct to do that but it works for 5.2 =)
pleasedontbelong
well, thank you very much, I'm doomed to use 5.2 I used some 5.3 featuers already like $var::call_method() and have to backport it to call_user_func(array($var,"call_method")) as I realized I need support for 5.2. I'll have a look if really wann do this for 5.2 with your solution. Don't get me wrong, its beautiful, but possibly not the way I want to walk. :)
evildead