2013-05-29 4 views
2

J'utilise Propel avec CodeIgniter. J'ai fait une classe MY_Model (qui s'étend CI_Model) qui utilise son constructeur pour charger Propel.Utilisation d'un espace de noms dans une classe étendue

Si vous êtes curieux:

class MY_Model extends CI_Model{ 
    public function __construct(){ 
     parent::__construct(); 

     require_once '/propel/runtime/lib/Propel.php'; 
     Propel::init('/build/conf/project-conf.php'); 
     set_include_path('/build/classes'.PATH_SEPARATOR.get_include_path()); 
    } 
} 

Alors, maintenant, quand je fais un nouveau modèle de CodeIgniter, il va charger Propel pour moi. La chose est, j'ai ajouté des espaces de noms à quelques-uns des modèles générés par Propel. J'ai pensé que je pourrais ajouter la ligne use Reports; dans le constructeur du modèle, mais non.

class Reports_model extends MY_Model{ 
    function __construct(){ 
     parent::__construct(); 
     use Reports; 
    } 
} 

Cela me donne

syntax error, unexpected T_USE

Ok, je pensais, nous allons essayer de le mettre à l'extérieur du constructeur:

class Reports_model extends MY_Model{ 
    use Reports; 

    function __construct(){ 
     parent::__construct(); 
    } 
} 

Maintenant je une plus longue erreur:

syntax error, unexpected T_USE, expecting T_FUNCTION

En dernier recours, j'ai ajouté le use Reports; avant la déclaration de classe:

use Reports; 

class Reports_model extends MY_Model{ 
    function __construct(){ 
     parent::__construct(); 
    } 
} 

Maintenant, j'ai encore plus d'erreurs!

The use statement with non-compound name 'Reports' has no effect
Class 'ReportsQuery' not found

Dans une autre fonction dans la classe, j'ai une ligne qui ne $report = ReportsQuery::create();. Alors, comment puis-je faire fonctionner la ligne use Reports;? Je n'ai vraiment pas envie d'ajouter Reports\partout.

Comment puis-je faire si je peux le faire:

$report = ReportsQuery::create(); 

au lieu de:

$report = Reports\ReportsQuery::create(); 
+0

Bonne question ... et mon suivi serait pourquoi PHP ne peut-il pas trouver l'espace de noms 'Reports'? je suppose que l'emplacement de la classe 'Reports_model' rend PHP tel qu'il ne sait pas où trouver' Reports'. Désolé, je ne suis pas un expert de l'espace de noms, mais vous pouvez demander ceci dans le groupe Google de Propel si vous n'obtenez pas de réponse ici! – jakerella

+0

@jakerella: L'espace de noms 'Reports' n'existe que dans les modèles de Propel. Ma conjecture est que le constructeur de 'MY_Model' n'était pas encore appelé, donc PHP ne sait pas où est l'espace de noms. –

+0

Riiiight ... hrm. Peut-être devrez-vous toujours initer Propel versus dans le constructeur du modèle? En d'autres termes, mettez-le dans une sorte de zone de démarrage (pas très familier avec CI). – jakerella

Répondre

2

Apparemment , le mot-clé use ne fait pas ce que je pensais. Cela indique simplement à PHP où chercher une classe.

Ce que je devais faire était d'utiliser le mot-clé namespace pour déclarer que ma classe se trouvait dans l'espace de noms Reports. J'ai ensuite dû lui dire d'utiliser MY_Model de l'espace de noms global.

namespace Reports; 
use MY_Model; 

class Reports_model extends MY_Model{ 
    function __construct(){ 
     parent::__construct(); 
    } 
} 

Je pourrais aussi faire class Reports_model extends \MY_Model{ au lieu de la ligne use MY_Model;. Le problème est maintenant que CodeIgniter ne peut pas trouver Reports_model parce qu'il est maintenant dans l'espace de noms Reports, et non dans l'espace de noms global. J'ai trouvé la solution à cela dans une autre question StackOverflow (https://stackoverflow.com/a/14008411/206403).

Il existe une fonction appelée class_alias qui est fondamentalement magique.

namespace Reports; 
use MY_Model; 

class_alias('Reports\Reports_model', 'Reports_model', FALSE); 

class Reports_model extends MY_Model{ 
    function __construct(){ 
     parent::__construct(); 
    } 
} 

Et cela fonctionne parfaitement!

+0

En fait, vous pouvez simplement ajouter '\\' avant l'espace de nom et y accéder dans la portée glbale. Nayjest voulait probablement dire ça. – itachi

+0

@itachi: Je le mentionne dans ma réponse: 'extends \ MY_Model'. Le problème est, j'utilise CodeIgniter, donc je ne peux pas le modifier pour ajouter les barres obliques. –

0

préfixe Juste toutes les classes sans espaces de noms par "\" dans le code avec namespaces

+0

Mais, comment puis-je obtenir mon code * dans * l'espace de noms? * C'est * la question ici. –

+0

Code ci-dessous "namespace BlahBlahBlah;" sera dans l'espace de noms BlahBlahBlah. Si vous avez défini une classe, vous pourrez utiliser cette classe en dehors de \ BlahBlahBlah \ MyClass Ou ajouter "use BlahBlahBlah \ MyClass;" dans le fichier où il sera utilisé et y accéder par nom de classe sans espace de nom. Notez que dans la construction "use" vous devez spécifier le nom complet de la classe namespaced, php ne peut pas importer toutes les classes de certains espaces de noms de cette façon. Si vous écrivez "use" en classe, cela sera interprété comme l'ajout d'un trait à cette classe, vous n'en avez pas besoin. – Nayjest

Questions connexes