2013-03-22 8 views
12

Ich habe festgestellt, dass wenn ich Namespacing verwende, das Laden von Klassen dynamisch nicht so funktioniert, wie wenn ich sie statisch lade. So zum Beispiel, ohne die Verwendung von Namensräumen der folgenden äquivalent sind in ihrer Wirkung eine Klasse instanziieren genannt FooBar:Dynamisches Laden von Klassen kann Namespace nicht adressieren/verwenden

$foobar = new FooBar(); 

und

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

Wenn jedoch bei der Verwendung von Namespacing Ich habe einige Code wie diesen :

<?php 

namespace Structure\Library; 

$foobar = new UserService(); 
$classname = "UserService"; 
$barfoo = new $classname; 
In diesem Fall

die vollständig qualifizierte Namen der UserService Klasse sind Structure\Library\UserService und wenn ich die voll qua verwenden lificed Name funktioniert es in beiden Fällen, aber wenn ich nur den Namen der Verknüpfung 'UserService' es nur funktioniert, wenn instanziiert mit der statischen Methode. Gibt es einen Weg, um es für beide zu arbeiten?

P.S. Ich benutze einen Autoloader für alle Klassen ... aber ich nehme an, dass das Problem vor der Autoloader passiert und die Klassenzeichenfolge bewirkt, die an den Autoloader übergeben wird.

+0

Verwirrt von, "es funktioniert nur, wenn mit der statischen Methode instanziiert". Wo benutzt du ein statisches '::'? Verständnis von ['Global Space'] (http://www.php.net/manual/en/language.namespaces.global.php)? – ficuscr

+0

Es tut mir leid, ich meinte die statische Referenz auf die Klasse nicht eine "statische Klasse". : ^) Explizit die Zeile '$ foobar = new UserService();' – ken

+0

Kannst du uns die Logik deines Autoloaders zeigen? Ich stelle mir vor, dass Sie den Namespace verwenden, um den Pfad zu berechnen, von dem die Klassendatei geladen werden soll. Ist das richtig? Kannst du deinen Namen '$ class' nicht innerhalb des Autoloaders" echo "nennen, um uns einen besseren Hinweis zu geben? Wie Allender geantwortet hat, stelle ich mir vor, dass der verarbeitete Klassenname den Namespace in einer Instanz enthält, ihn aber nicht in einer anderen enthält. Im Wesentlichen ähnelt die letzte Zeile Ihres Codes dem Schreiben: '$ barfoo = new \ UserService();', was fehlschlägt, weil die Klasse nicht im globalen Namespace ist. – cartbeforehorse

Antwort

4

Dies wäre die nächste Lösung sein, die ich finden kann:

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

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

Viel Glück!

Update 1

Dies könnte zur weiteren Lektüre gut sein: http://www.php.net/manual/en/language.namespaces.importing.php

use My\Full\UserService as UserService; 

Update 2

So weit habe ich jetzt:

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; 

Oder diese Variante für mehr Flexibilität:

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

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

Docs

+0

Ich habe versucht, mit der Syntax verwenden, die Sie vorschlagen, aber es scheint nicht für das dynamische Laden von Klassen zu helfen (tut es für statische). – ken

+0

Haben Sie den Link gelesen? Wenn Sie die andere Klasse mit dem Ort verknüpfen (verwenden), dann sollten Sie einfach folgendes tun können: '$ obj = new Another;', in Ihrem Fall '$ barfoo = new UserService;'. Natürlich muss das obige Beispiel (My \ Full \) durch den Pfad ersetzt werden, in dem sich die Klasse befindet. –

+0

Ja, aber der Operator 'use' scheint nicht ausgewertet zu werden, wenn eine Klasse dynamisch instanziiert wird. Ich benutze 'use' viel und in diesem Fall habe ich es explizit vergebens versucht. In vielen Fällen ist dies ein Fall, in dem Sie nicht wirklich "verwenden" möchten, obwohl ich versuche, eine dynamische Antwort zu erstellen und die use-Anweisung statisch ist. Wie auch immer, es funktioniert nicht. ; ^) – ken

10

Ich denke, dies ein Fall von der Lektüre der Dokumentation. Siehe Beispiel 3:

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

Scheint meinen früheren Kommentar zu bestätigen.

<?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

danke @cartbeforehorse, ich werde mir das in ein paar Wochen anschauen. Entschuldigung für meinen Mangel an Antwort, aber die Frage ist vor 6 Monaten und irgendwo in der Lücke habe ich alles funktioniert * gut genug *. Das sagte, ich fühle immer noch, dass ich mein Verständnis begründen muss. – ken

+0

@ken Ich fülle diese Art von Fragen für meine eigene zukünftige Referenz, so viel wie für Ihre Info Ich habe keine Antwort erwartet und mir vorgestellt, dass sich Ihre Arbeit in den dazwischen liegenden 6 Monaten ziemlich weiterentwickelt hätte. – cartbeforehorse

+0

@ken Eigentlich ist diese Antwort (technisch) fast identisch mit Allendar. Ich habe jedoch das Format dieser Antwort gefunden unnötig sein y schwer zu folgen. – cartbeforehorse

Verwandte Themen