Variable, getInstance et ... T_PAAMAYIM_NEKUDOTAYIM [Résolu]

Signaler
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
-
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
-
Bonsoir à tous :)
Me voila confronté à un petit probleme.
J'aimerai récuperer l'instance de classes avec le singleton getInstance de n classes contenues dans un tablea $aClasses.
pour ce faire, je fait un foreach ($aClasses as $classe)
mais le probleme, c'est que si je fait un $classe::getInstance () BAM j'ai un T_PAAMAYIM_NEKUDOTAYIM (mon pote celui la ::) ).
Comment y remédier ?

Merci de votre aide :)

8 réponses

Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Qu'elle soit privée, protégée ou publique ne change rien en fait. Le truc, c'est l'endroit où elle est appelée. Un require, au fond, ça ne fait qu'ajouter à ta page (la page appelante) le source de la page que tu inclus.
donc si j'ai :
page class.A.php :
<?php
class A {
  public function myMethod() {
    require_once 'pageB.php';
  }
}

page appelantephp :
<?php
require_once 'class.A.php';
$obj = new A;
$obj->myMethod();
?>

tu auras dans appelante.php le contenu de ton fichier pageB.php.
Si tu fais ça:
page class.A.php :

<?php

class A {
  public function build() {
    $this->myMethod();
  }

  private function myMethod() {

    require_once 'pageB.php';

  }

}


page appelantephp :

<?php

require_once 'class.A.php';

$obj = new A;
$obj->build();

?>
ça ne change strictement rien, l'effet sera le même, qu'au-dessus.
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
en fait mon probleme est plus complexe que ca

j'ai ma classe core qui va charger les classes contenues dans le tableau
j'aimerai récuperer leur instance par getInstance() plutot que de faire un new theClass ();
Le probleme, c'est que j'inclue les classes à la volées avec la fonction magique __autoload.
Pour faire encore plus compliqué, j'ai trois type de classe. J'aimerai que en fonction du type de classe (module, plugin, etc), __autoload aille inclure la classe dans le bon repertoire.
Il se peux que j'aie deux classes ayant le meme nom mais pas dans le meme repertoire. Je ne peux donc pas faire un "je test si la classe existe dans le premier dossier, puis dans le second, puis etc"

Comment faire ? :)
une idée ?
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
39
"J'aimerai que en fonction du type de classe (module, plugin, etc), __autoload aille inclure la classe dans le bon repertoire."=> a mon avis c'est pas possible
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Hello,

pour le getInstance() : tu stockes des INSTANCES ou des CLASSES ? Parce que :

class A {
  public static getInstance() {
  }
}

$o = new A;
$o::getInstance(); // wrong, hein!

Mais si tu as : $o = 'A';
$o::getInstance();
devrait fonctionner.

Et __autoload() n'interviendra pas ici car il ne s'occupe que d'instancier via le constructeur.

Ensuite, avoir des classes portant le même nom mais pas dans le même répertoire si tu n'as pas de moyen de prioriser n'est pas une bonne idée. En tous cas, pas avant PHP6 et les espaces de nom.
Moi j'ai un truc du genre : un site, avec un répertoire de classes. Mais aussi, à la racine du serveur web, un répertoire 'public' dans lequel se trouvent toutes les lasses génériques (abstraction de bdd par exemple).
L'autoload des sites va d'abord chercher dans le répertoire class des sites, et s'il ne trouve pas ici, il va ensuite dans public (et ce seulement si class_exists() renvoie faux auparavant). Je priorise : si j'ai "surchargé" le répertoire public en mettant une classe dans le répertoire class du site qui existe déjà dans le répertoire public, c'est qu'il y a une raison : je l'ai sans doute modifiée. Je veux donc que la priorité soit données à ces classes, puis à public.

Et si je veux vraiment encore plus surcharger...que je dois aller chercher une classe encore ailleurs et qu'elle porte le même nom qu'une classe de public ou du répertoire class, je fais un require dessus. Vu que l'autoload (enfin le mien) vérifie d'abord ce que retourne class_exists(), il ira bien prendre la classe que je viens d'inclure dans ce cas-ci.
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
En fait excusez moi, j'ai mal évalué mon probleme.
Je vais m'expliquer un peu mieux

J'ai une structure de dossier comme ceci :
/content/components/*
/content/modules/*
/content/plugins/*

avec * qui correspond à un dossier (du même nom de la classe (genre ./news/) suivi du nom de la classe.class.php (./news/news.class.php)

J'ai un fichier de configuration qui me dit quels composants, quels modules, et quels plugins charger.
dans ma classe core, je fait une boucle sur $aComponents pour charger chaques composants à la suite.
Le probleme, c'est que si je fait un require_once dans __construct de la classe core, les autres classes n'auront pas acces au contenu du require_once (apparement, il reste dans le scopage de la classe core).

Hier je voulais instancier les classes, mais c'est totalement inutile, en fait, je voudrais inclure les classes donc j'ai besoin, mais dans le scopage global.
Comment faire ?

(j'espere avoir été clair dans ma description :/)
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Hello,

il ne faut pas le faire dans le constructeur en effet.
Mais tu peux le faire dans une autre méthode publique.
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
si je le fait dans une autre méthode public, le scopage de l'inclusion sera global ?
Messages postés
1123
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1
okay parfait alors :)
Ca marche partout, il faut juste que ce ne soit pas fait dans le constructeur.... okay !!! :)

Merci bien pour ces détails :)

Au fait, t'a pas répondu à mon dernier msg ? :p