2013-03-22 7 views
12

Ho notato che quando utilizzo il namespacing il caricamento delle classi in modo dinamico non funziona come quando le sto caricando staticamente. Così, per esempio, senza l'uso di spazi dei nomi qui di seguito sono equivalenti nella loro azione di istanziare una classe denominata FooBar:Il caricamento dinamico delle classi non può indirizzare lo spazio dei nomi/

$foobar = new FooBar(); 

e

$classname = "FooBar"; 
$foobar = new $classname; 

Tuttavia, se quando si utilizza namespacing ho qualche codice come questo :

<?php 

namespace Structure\Library; 

$foobar = new UserService(); 
$classname = "UserService"; 
$barfoo = new $classname; 

In questo caso il nome completo della classe UserService è Structure\Library\UserService e se uso il pieno qua il nome completo funziona in entrambi i casi, ma se utilizzo solo il nome di scelta rapida di 'UserService', lo solo funziona quando viene istanziato con il metodo statico. C'è un modo per farlo funzionare per entrambi?

P.S. Sto utilizzando un caricatore automatico per tutte le classi ... ma suppongo che il problema stia succedendo prima del il caricatore automatico e sta effettuando la stringa di classe che viene passata al caricatore automatico.

+0

Confuso da ", funziona solo se istanziato con il metodo statico". Dove stai usando uno statico '::'? Comprendere la comprensione di ['Global Space'] (http://www.php.net/manual/en/language.namespaces.global.php)? – ficuscr

+0

No, mi spiace, intendevo il riferimento statico alla classe non una "classe statica". : ^) Esplicitamente, la riga che dice '$ foobar = new UserService();' – ken

+0

Puoi mostrarci la logica del tuo autoloader? Immagino che all'interno, tu usi lo spazio dei nomi per calcolare il percorso da cui caricare il file di classe. È giusto? Non puoi 'echo' il tuo nome' $ class' all'interno del caricatore automatico, per darci un indizio migliore? Come ha risposto Allender, immagino che quello che sta succedendo è che il nome della classe in elaborazione includa lo spazio dei nomi in una istanza, ma non lo include in un'altra. Essenzialmente, l'ultima riga del tuo codice è simile alla scrittura: '$ barfoo = new \ UserService();', che fallisce, perché la classe non è nello spazio dei nomi globale. – cartbeforehorse

risposta

4

Questa sarebbe la soluzione più vicina che posso trovare:

define('__NSNAME__', __NAMESPACE__.'\\'); 

$foobar = new UserService(); 
$classname = __NSNAME__."UserService"; 
$barfoo = new $classname; 

Buona fortuna!

Update 1

Questo potrebbe essere buono per ulteriori letture: http://www.php.net/manual/en/language.namespaces.importing.php

use My\Full\UserService as UserService; 

Update 2

Questo è quanto ho ottenuto ora:

namespace Structure\Library\Home; 

class UserService { 

} 

namespace Structure\Library; 

use Structure\Library\Home\UserService as UserService; 

define('UserService', __NAMESPACE__.'\\Home\\UserService', TRUE); 

$foobar = new UserService(); 
$classname = UserService; 
$barfoo = new $classname; 

O questa variante per una maggiore flessibilità:

define('Home', __NAMESPACE__.'\\Home\\', TRUE); 

$foobar = new UserService(); 
$classname = Home.'UserService'; 
$barfoo = new $classname; 

Docs

+0

Ho provato a utilizzare la sintassi di utilizzo suggerita ma non sembra essere di aiuto per il caricamento dinamico della classe (lo fa per statico). – ken

+0

Hai letto il link? Se colleghi l'altra classe alla sua posizione (uso), dovresti essere in grado di fare: '$ obj = new Another;', nel tuo caso '$ barfoo = new UserService;'. Fuori campo il mio esempio sopra (My \ Full \) deve essere sostituito con il percorso in cui risiede la classe. –

+0

Sì, ma l'operatore 'use' non sembra essere valutato durante l'istanza dinamica di una classe. Uso 'use' molto e in questo caso l'ho provato esplicitamente senza successo. In molti modi, questo è un caso in cui non si vorrebbe veramente usare 'use' anche se sto cercando di creare una risposta dinamica e l'istruzione use è statica. Ad ogni modo, non funziona. ; ^) – ken

10

Credo che questo sia un caso di lettura della documentazione. Vedi l'esempio 3:

http://php.net/manual/en/language.namespaces.importing.php

sembra confermare il mio commento precedente.

<?php 
    namespace foo\bar; 

    $classStr = "myClass";  
    $nsClass = "\\foo\\bar\\myClass"; 

    $x = new myClass; // instantiates foo\bar\myClass, because of declared namespace at top of file 
    $y = new $classStr; // instantiates \myClass, ignoring declared namespace at top of file 
    $z = new $nsClass // instantiates foo\bar\myClass, because it's an absolute reference! 
?> 
+0

grazie a @cartbeforehorse, guarderò tra qualche settimana. Scusa la mia mancanza di risposta ma la domanda è di 6 mesi fa e da qualche parte nel gap ho tutto funzionante * abbastanza bene * Detto questo, sento ancora che ho bisogno di radicare la mia comprensione – ken

+0

@ken Riempio questi tipi di domande per il mio riferimento futuro, tanto quanto per le tue informazioni. non mi aspettavo una risposta, e immaginavo che il tuo lavoro si sarebbe spostato un bel po 'nei sei mesi intermedi. – cartbeforehorse

+0

@ken in realtà, questa risposta è (tecnicamente) quasi identica a Allendar.Tuttavia, ho trovato il formato di quella risposta essere inutile e difficile da seguire. – cartbeforehorse

Problemi correlati