2010-12-10 2 views
3

Editer:
* Note: J'utilise PHP 5.2 pour le moment, malheureusement. Je ne peux pas trouver un hôte pas cher décent offrant 5,3 ...Comment créer une constante dans une sous-classe à utiliser dans une méthode trouvée dans une classe parent en PHP 5.2?


En PHP, self fait référence à la classe dans laquelle la méthode appelée est définie. Cela signifie que si vous ne remplacez pas une méthode dans la classe enfant, le mot clé self fera référence à la classe parente, même lorsqu'elle est appelée à partir de l'enfant.

Par exemple, ce code:

<?php 

class ParentClass { 
    const NAME = "ParentClass"; 
    public function showName() { 
    echo self::NAME . "<br />\n"; 
    } 
} 

class ChildClass extends ParentClass { 
    const NAME = "ChildClass"; 
    public function __construct() { 
    echo self::NAME . "<br />\n"; 
    } 
} 

$test = new ChildClass(); 
$test->showName(); 

?> 

créerons cette sortie:

ChildClass 
ParentClass 

Ce que je veux faire est de créer une méthode par défaut (par exemple showName() dans l'exemple ci-dessus) qui existe dans une classe parent avec des constantes définissant les valeurs par défaut à utiliser. Chez l'enfant, je veux être en mesure de remplacer ces constantes (notez le const dans la définition de l'enfant ci-dessus), et ont ces valeurs sont utilisées lorsque j'appelle la méthode sur une instance de l'enfant.

En bref, comment puis-je faire en sorte que la sortie de l'exemple ci-dessus serait ...

ChildClass 
ChildClass 

... sans avoir à dupliquer le code du parent chez l'enfant?

+0

J'utilise ServerGrove et ils offrent l'hébergement 5.3 pour un prix raisonnable. – CaseySoftware

+0

@CaseySoftware: Bookmarked, merci. Je vais devoir vérifier quelques critiques pour cela, etc. mais cela semble prometteur. J'ai prévu d'aller avec WebFaction, mais la différence de prix ne semble pas importante. WF fait 5.3, mais ils le font en exécutant un autre Apache sous votre compte, en mangeant de la RAM, etc. - pas nécessairement ce que je veux. – AgentConundrum

Répondre

5

je crois que le sel syntaxique selon votre cas est:

print constant(get_class($this)."::NAME"); 
+0

Magnifique! Eh bien, au moins moins hideux qu'il pourrait l'être. Merci! – AgentConundrum

+2

Pour les personnes recherchant une solution php5.3 ou supérieure, vous pouvez utiliser le mot-clé 'static ::' au lieu de 'self ::'. – phemios

9

Essayez

function showName() { 
    return static::NAME; 
} 

Il utilise late static binding:

PHP 5.3.0, PHP implémente une fonctionnalité appelée fixations fin statiques qui peuvent être utilisés pour faire référence à la classe appelée dans un contexte d'héritage statique . Plus précisément, les liaisons statiques en retard fonctionnent en stockant la classe nommée dans le dernier "appel sans renvoi" . En cas de appels de méthodes statiques, c'est la classe explicitement nommée (généralement celui sur gauche de l'opérateur ::); dans le cas des appels de méthode non statiques, il s'agit de la classe de l'objet. Un "forwarding call" est un static qui est introduit par self ::, parent ::, static ::, ou, si vous montez dans la hiérarchie de classe , forward_static_call(). Les get_called_class fonction () peut être utilisé pour récupérer une chaîne avec le nom de la classe appelée et statique :: présente sa portée.

EDIT: Pour 5.2.x

Si vous n'avez pas 5.3.0 vous ne serez pas en mesure de tirer profit de cela. Une solution commune hack consiste à créer un cache statique (par ex.private static $statics = array()) référencé par nom de classe enfant. Il vous oblige à suivre l'héritage de l'objet pour remplacer la valeur de __construct et à définir explicitement les statistiques qui sont "héritables". Par exemple, SilverStripe utilise cette technique dans l'ORM Sapphire pour contourner les limitations de liaisons statiques PHP. Ils définissent un base Object class et diverses fonctions de gestion de variables statiques.

+0

J'aurais dû être plus clair, je suis limité à PHP 5.2 pour le moment. 5.3 n'a pas encore une bonne disponibilité sur les hôtes partagés. – AgentConundrum

+0

Pourquoi cela fonctionne avec constant, alors que son nom l'indique dans un contexte d'héritage 'static'? –

1

Peut-être juste à cause de votre petit exemple, mais le référencement « auto » ne semble pas nécessaire.

Je voudrais juste faire:

class ParentClass { 
    public function showName() { 
    echo $this->name() . "<br />\n"; 
    } 

    public static function name() { 
    return "ParentClass"; 
    } 
} 

class ChildClass extends ParentClass { 
    public function __construct() { 
    echo $this->name() . "<br />\n"; 
    } 
    public static function name() { 
    return "ChildClass"; 
    } 
} 

$test = new ChildClass(); 
$test->showName(); 

Sortie:

ChildClass 
ChildClass 
1

L'utilisation static::CONSTNAME retournera la bonne valeur.

Questions connexes