Problem
Sie nutzen in Ihrer Applikation diverse Bibliotheken oder Frameworks und wollen Konflikte zwischen eigenen Klassen und Framework-Klassen mit identischen Namen vermeiden. Sie möchten dabei aber nicht den in PHP häufig angewandten Kompromiss eingehen und den Klassennamen verkomplizieren (z.B. MeinProjekt_MeineTeilanwendung_Meine-Klasse
).
Lösung
Durch die Verwendung von Namespaces, die ab PHP 5.3 zur Verfügung stehen, können Sie eine saubere Trennung der Namensräume erreichen, ohne den Klassennamen künstlich zu verkomplizieren. Das folgende Codebeispiel zeigt, wie das aussehen könnte:
namespace net\php\pear\Date { class DateTime { public function __construct() { print __CLASS__ . " created\n"; } } } namespace de\oreilly\phpckbk { class DateTime { public function __construct() { print __CLASS__ . " created\n"; } } $oreillyDateTime = new DateTime(); use net\php\pear\Date; $pearDateTime = new Date\DateTime(); $phpDateTime = new \DateTime(); print_r($phpDateTime); }
Wie Sie sehen, werden im gezeigten Codebeispiel drei Klassen mit identischem Namen (DateTime
) verwendet. Wir selbst bewegen uns im Namensraum de\oreilly\phpckbk
und haben dort die Klasse DateTime
definiert. Diese kann also ohne weitere Namensraumangabe
instantiiert werden. Durch Angeben des entsprechenden Namensraums können wir genauso einfach die PEAR-Klasse DateTime
(Namespace net\php\pear\Date1) wie auch die von ext/date
im globalen Namensraum bereitgestellte Klasse DateTime
nutzen. Das angeführte
Skript läuft in PHP 5.3 ohne Fehler durch und erzeugt die folgende Ausgabe:
de\oreilly\phpckbk\DateTime created
net\php\pear\Date\DateTime created
DateTime Object
(
[date] => 2009-04-26 13:45:01
[timezone_type] => 3
[timezone] => Europe/Berlin
)
Diskussion
In PHP-Versionen vor 5.3 gab es keine Unterstützung für Namensräume. Um Konflikte zwischen Klassennamen zu vermeiden, wichen Entwickler in der Regel auf unbequem lange Klassennamen aus. So heißt im Zend Framework eine Klasse Zend_Controller_Dispatcher_Standard
. Beim Einsatz von PHP-Namespaces könnte man diese z.B. in den Namensraum com\zend\framework\controller
legen und StandardDispatcher
nennen. Dass auch die umständliche Benennung von Klassen nicht die perfekte Lösung ist, zeigte sich im November 2005, als das Release von PHP 5.1.0 die Klasse Date
der Erweiterung ext/date einführte. Das zog einen Namenskonflikt mit der gleichnamigen Klasse Date
aus dem PEAR::Date-Paket nach sich, und alle Skripten, die das PEAR-Paket nutzten, funktionierten auf einen Schlag nicht mehr. Die Verwendung von Namensräumen löst dieses Problem.
Siehe auch
Es gibt keine einheitliche Regelung für die Benennung von Namensräumen. In XML-Sprachen verwendet man üblicherweise URLs (siehe http://de.wikipedia.org/wiki/Liste_der_XML-Namensräume). In der Programmiersprache Java befinden sich alle Klassen im Namensraum java.*, in Open Source-Projekten werden oft URLs verwendet, jedoch in umgekehrter Reihenfolge. Die Volltext-Suchmaschine Lucene benutzt als Namensraum z.B. org.apache.lucene.*. Letztendlich liegt die Wahl des Namensraums bei Ihnen, die Verwendung einer URL als Namensraum hat jedoch den Vorteil, dass die Verbindung zwischen Ihrem Quellcode und der zugehörigen Webseite hergestellt werden kann (z.B. net\php\pear
für http://pear.php.net).
Auszug aus der Neuauflage des PHP5 Kochbuchs