2010-10-02 4 views
0

J'ai les classes suivantes.php oop extends problème

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(){ 

    } 
} 

puis l'init comme si

$test = new sub(); 

mon problème est que je veux vérifier si le sous base __construct a une méthode foo. mais il ne semble pas avoir cette méthode. Quelqu'un peut-il me dire où je me suis trompé?

+2

Pourquoi voudriez-vous vérifier une méthode 'foo'? Et votre implémentation singleton est un peu étrange. – NullUserException

+0

Je veux vérifier foo car il peut appeler une méthode par défaut s'il n'est pas trouvé. pourquoi le singleton est-il étrange? – Val

+2

Peut-être parce que votre méthode singleton instancie une classe totalement différente appelée 'controller'? – BoltClock

Répondre

3

Bien que vous appelez parent::singleton() de sub classe, mais le singleton() vous crée toujours instance de classe base (parce que vous faites new base()), qui n'a pas votre méthode foo().

En général, vous ne devez utiliser/appeler aucune méthode de la classe de base, qui n'y est pas définie. Parce que cela rend votre code non propre: que se passe-t-il si vous implémentez une autre classe qui étend votre classe base, mais oublie d'implémenter la méthode foo()? Si vous êtes sûr, que cette méthode foo() sera toujours implémentée par n'importe quelle classe enfant - vous pouvez définir en méthode abstraite dans la classe de base - alors n'importe quelle classe enfant être forcé de l'implémenter. Ou au moins comme une méthode vide dans la même classe de base ... De cette façon, votre code sera propre et structuré.

+0

Erreur fatale: Impossible d'instancier la base de classe abstraite dans ... fichier.php ... sur la ligne 28 – Val

3

La méthode foo n'existe pas car le singleton en cours de création est une instance de base. Voilà ce qui se passe:

  1. Créer une instance de sub
  2. Constructor de sub obtient l'instance singleton.
  3. singleton() crée une instance de base
  4. base vérifie constructeur si la classe base contient une méthode nommée foo. Ce ne est pas.

Modifier

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

Dans ce cas, le singleton est superflu. Au lieu de cela, vous pouvez commencer avec une classe d'usine de base qui implémente le modèle de contrôleur frontal désiré:

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'); 
+0

qui a du sens ... oop fait mon cap ...:) Alors, comment pourrais-je faire à ce sujet? – Val

+0

Je ne suis pas sûr à 100% de ce que vous essayez de faire, mais je vais essayer de le faire: vous voulez que chaque sous-classe de 'base' ait une méthode statique' singleton() 'qui retourne un singleton du type de sous-classe. Est-ce ceci? – leepowers

+0

J'ai reçu une URL par exemple. 'site.com/sub/foo' donc la classe sub est appelée et je veux que la base vérifie si foo n'existe pas alors je vais casser le code ... foo peut être n'importe quoi tant qu'il existe comme méthode sur sub classe – Val