2008-12-03 5 views
3

J'ai une classe Page qui crée une instance de DB, qui est nommée $db.Pouvez-vous obtenir les variables d'une classe appelante?

Dans le __construct() de Page, je crée le nouvel objet $db et je tire un tas de données de configuration à partir d'un fichier.

Maintenant, la classe DB présente une méthode qui _connectToDB() (tentatives) pour se connecter à la base de données.

Existe-t-il un moyen dans la classe DB d'appeler le tableau de configuration de la classe parente? Je ne veux pas faire de variables globales si je ne le dois pas et je ne veux pas récupérer les données de configuration deux fois.

Pseudo code pourrait ressembler à quelque chose comme ça ...

$dbUsername = get_calling_class_vars(configArray['dbUserName']); 

Répondre

6

je trouve qu'il est souvent plus facile d'initialiser tous les objets « importants » à proximité de tout les variables dont ils ont besoin de savoir. Vous pouvez essayer cette façon:

/* Code to get config variables here */ 
$DB = new DB($config); 
/* You might want to delete the database password from $config here */ 
$Page = new Page($config, $DB); 

En procédant ainsi, signifie que vous pouvez également faire la vérification de type sur l'objet de base de données si vous voulez:

class Page { 
    function __construct(array $config, DBClass $db) { } 
} 
+0

C'est à peu près ce que j'ai suggéré sans aucun code :) – grepsedawk

+0

Cela ressemble à ce que je devrais implémenter, et merci pour le conseil de unset() 's les db config vars, bonne réflexion ! – alex

2

Pourquoi passer pas les paramètres de configuration à la fonction connectToDb ou de transmettre les données de configuration au constructeur de la classe DB.

Et au répertoire répondre à la question: vous ne savez rien sur le contexte d'appel extérieur dans votre contexte actuel.

+0

Je pourrais faire cela, je pensais juste qu'il pourrait y avoir un moyen plus facile .... – alex

1

Voir debug_backtrace() pour obtenir des informations sur l'appel de classes ou d'objets.

Ensuite, voir Reflection pour obtenir plus d'informations sur les propriétés d'une classe ou d'un objet donné.

éditer: Mais pour ce que ça vaut, je vous recommande également de passer les paramètres spécifiques dont vous avez besoin. Le référencement des données de l'appelant constitue probablement Content Coupling.

+0

J'ai décidé d'aller avec la solution ci-dessus j'ai marqué comme accepté. J'apprécie toute votre aide jusqu'à présent Bill :) – alex

0

Vous pouvez transmettre à l'enfant une référence au parent. Par exemple:

class Parent { 
    function __construct() { 
    $this->myChild = new Child($this); 
    } 
    public function doSomething() {} 
} 

class Child { 
    function __construct(Parent $parent) { 
    $parent->doSomething() 
    } 
} 

Vous pouvez trouver cela étrange, puisque vous êtes encore dans le constructeur du parent, et donc votre objet parent n'est pas complètement construit encore. Mais vous pouvez toujours utiliser $ this comme une référence à vous même dans le constructeur. Vous devez juste faire attention à ce que votre enfant ne se réfère pas à des choses dans le parent qui n'ont pas encore été initialisées.

0

En général il n'y a pas moyen facile de fais ceci. mais comme un problème de conception générale je peux voir pourquoi vous évitez les variables globales, mais dans le cas d'une configuration à l'échelle de l'application, il est parfaitement raisonnable d'avoir un accès global aux propriétés.

vous pouvez rendre vos données de configuration globale ou simplement passer les propriétés nécessaires à l'initialisation de l'objet db.

1

Vous pouvez utiliser static si vous souhaitez partager des variables sans passer celles-ci:

class page{ 
    static $configArray = []; 
    function doWhatever(){ 
     $db = new DB(); 
     $db->connectToDB(); 
    } 
} 
class DB{ 
    function connectToDB(){ 
     $dbUsername = page::$configArray['dbUserName']; 
    } 
} 

Dans ce cas, est logique d'avoir ces données static, parce que même si vous avez un plusieurs instances de la classe de page, les paramètres de configuration doivent toujours être les mêmes.

Quoi qu'il en soit, je pense que cela pourrait être mieux de construire et de conserver le $ configArray seulement dans la classe DB. Si vous voulez l'appeler de l'extérieur, vous pouvez utiliser la même logique static.

Questions connexes