Konstanten im Zusammenhang mit Namespaces verwenden30 Dez

Von Julian am 30.12.2009. Es wurde noch kein Kommentar hinterlassen. Du kannst einen Kommentar hinterlassen oder trackbacken.

Da will man nach langer Zeit mal wieder etwas mit php hantieren und schon stößt man wieder auf kleine Unsinnigkeiten und Verhalten, die man so zunächst nicht erwarten würde.
Es geht um Konstanten und Namespaces.

Namespaces sind eigentlich eine sehr praktische Sache. Sie strukturieren Projekte und trennen verschiedene Systeme (welcher Art auch immer) voneinander, so dass man beispielsweise verschiedene Frameworks in einem Projekt verwenden kann. In meinen Augen eine wunderbare Sache.
Namespaces lassen sich auch ganz leicht verwenden:

<?php
namespace MyProject;
function foo(){
 echo 'bar';
}
?>

Eine besondere Einführung zu Namespaces möchte ich nun auch nicht großartig halten, schließlich gibt es sie nun schon einige Zeit und es wurden genügend Blog-Artikel darüber verfasst. Allerdings möchte ich auf die – meiner Meinung nach – intuitive Verwendung von Funktionen hinweisen:

foo();

.. gibt nun logischerweise bar aus. Ändere ich den Code auf folgende Weise:

<?php
namespace {
 function foo(){
  echo 'bar';
 }
}
 
namespace MyProject {
 foo();
}
?>

Dann sollte das selbe ausgegeben werden. Denn wenn eine Funktion im aktuellen Namespace nicht existiert, wird im globalen Namespace nach ihr gesucht. Somit kann man ganz gewöhnlich auf vordefinierte Funktionen von php wie beispielsweise sort() ohne ein vorangestellten Backslash zugreifen, wie man es bei Klassen machen müsste.

Deklariert man nun aber eine Konstante innerhalb eines Namespace, geschieht zunächst etwas Unerwartetes:

<?php
namespace MyProject\config {
 define('MY_CONSTANT', 'const');
}
namespace MyProject {
 echo config\MY_CONSTANT;
}
?>

Ein Fehler tritt auf: Die Konstante “const\MY_CONSTANT” ist nicht definiert. Wie? Aber ich befinde mich doch beim Aufruf ganz offensichtlich im Namespace “MyProject” und greife auf eine Konstante im Subnamespace “const” zu. Jetzt kommt die Eigenheit: MY_CONSTANT wurde global definiert und müsste folgendermaßen abgeändert werden:

<?php
namespace MyProject\config {
 define(__NAMESPACE__.'\MY_CONSTANT', 'const');
}
namespace MyProject {
 echo config\MY_CONSTANT;
}
?>

Damit ist der Name der Konstante aber nichts anderes als ein gewöhnlicher String, dem nun der Pfad des Namensraum vorangestellt wurde. Über get_defined_constants(true) sieht man weiterhin: Eine wirkliche Unterteilung in Namensräume gibt es bei Konstanten nicht, sie werden einfach an Hand des Backslashs in Namensräume getrennt.
Sieht für mich also beinahe nach einem Workaround aus ..

Zumindest sollte man sich das merken, bevor man verzweifelt nach irgendwelchen logischen Fehlern sucht – so wie ich. Ein kleines Good-to-know also ;)

Hinterlasse einen Kommentar

© 2009 GlobalIndustry-Project Blog