tags:

views:

84

answers:

2

i have the following classes.

class base {

    private function __construct(){
        //check if foo method exists 
        //$this->foo(); // if it exists
    }

    public static function singleton(){
        if(!isset(self::$singleton)){
            self::$singleton = new base();
        }
        return self::$singleton;
    }
}

class sub extends base{
    public function __construct() {
        parent::singleton();
    }

    public function foo(){

    }
}

then init it like so

$test = new sub();

my problem is that I want to check on base __construct if the sub has a foo method. but it doesn't seem to have this method.

can someone tell me where have I gone wrong?

+3  A: 

Although you call parent::singleton() from sub class, but the singleton() still creates you instance of base class (because you do new base()), which does not have your foo() method.

In general you shouldn't use/call any methods from base class, which aren't define in it. Because it makes your code not clean: what if you will implement some another class which extends your base class, but forgets to implement the foo() method? You can end up with fatal errors quite fast...

If you are sure, that this foo() method will be always implemented by any child class - you can define in as abstract method in base class - then any child class will be forced to implement it. Or at least as an empty method in the same base class... This way your code will be clean and structured.

Laimoncijus
Fatal error: Cannot instantiate abstract class base in ...file.php... on line 28
Val
+3  A: 

The method foo will not exist as the singleton being creating is an instance of base. Here's what's happening:

  1. Create an instance of sub
  2. Constructor of sub gets the singleton instance.
  3. singleton() creates an instance of base
  4. base constructor checks if the base class contains a method named foo. It does not.

Edit

i got a url e.g. site.com/sub/foo so the class sub is called and i want the base to check if foo does not exist then i will break the code... foo can be anything as long as it exists as a method on sub class

In this case the singleton pattern is superfluous. Instead, you can start with a basic factory class that implements the desired front controller pattern:

class factory {
  static public function go($path) {
    list($type, $action) = explode('/', $path);
    if (class_exists($type) &&   // Does the requested type/class exist?
        is_subclass_of($type, 'factory') &&  // Basic security. Make sure URL requests can't create an instance of *any* PHP class
        method_exists($type, $action))  // Check requested method/action
    {
      $o = new $type;
      $o->$action();
    }
  }
}

class sub extends factory {
  public function foo() {
    echo('To foo or not to foo that is the question.');
  }
}

factory::go('sub/foo');
pygorex1
that makes sense... oop is doing my heading... :) so how would I go about this?
Val
I'm not 100% sure what you're trying to do, but I'll take a stab at it: you want every subclass of `base` to have a static `singleton()` method that returns a singleton of the subclass type. Is this it?
pygorex1
i got a url e.g. `site.com/sub/foo` so the class sub is called and i want the base to check if foo does not exist then i will break the code... foo can be anything as long as it exists as a method on sub class
Val