Namespaces verwenden: Grundlagen
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
Bevor die Verwendung von Namespaces besprochen wird, ist es wichtig zu
verstehen, woher PHP weiß, welches Element mit Namespace vom Code
angefordert wird. Eine einfache Analogie kann zwischen PHP-Namensräumen und
einem Dateisystem gesehen werden. Es gibt drei Möglichkeiten, mit denen man
auf eine Datei in einem Dateisystem zugreifen kann:
-
Relative Dateinamen wie
foo.txt
. Dies wird zu
aktuellesVerzeichnis/foo.txt
aufgelöst, wenn
aktuellesVerzeichnis
das gerade geöffnete Verzeichnis
ist. Wenn also das aktuelle Verzeichnis /home/foo
ist, so wird dies als /home/foo/foo.txt
aufgelöst.
-
Relative Pfade wie
unterVerzeichnis/foo.txt
. Dies wird zu
aktuellesVerzeichnis/unterVerzeichnis/foo.txt
aufgelöst.
-
Absolute Pfadangaben wie
/main/foo.txt
. Dies wird zu
/main/foo.txt
aufgelöst.
Das gleiche Prinzip kann auf Elemente mit Namespaces in PHP angewandt werden.
Zum Beispiel kann eine Klasse auf drei Arten angesprochen werden:
-
Unqualifizierte Namen oder ein Klassenname ohne Präfix, wie etwa
$a = new foo();
oder
foo::staticmethod();
. Falls der aktuelle Namespace
aktuellerNamespace
ist, so wird dies zu
aktuellerNamespace\foo
aufgelöst.
Ist der Code globaler Code ohne Namespaces, so wird dies zu
foo
aufgelöst.
Es gibt eine Ausnahme hierzu: Unqualifizierte Namen für Funktionen und
Konstanten werden zu globalen Funktionen und Konstanten aufgelöst,
wenn die Funktion oder Konstante im Namespace nicht definiert ist.
Siehe auch Namespaces verwenden:
Rückgriff auf globale Funktion/Konstante für weitere Details.
-
Qualifizierte Namen oder ein Klassenname mit Präfix, wie etwa
$a = new unterNamespace\foo();
oder
unterNamespace\foo::staticmethod();
.
Wenn der aktuelle Namespace aktuellerNamespace
ist, so
wird dies als
aktuellerNamespace\unterNamespace\foo
verstanden.
Wenn der Code global und ohne Namespaces ist, so wird dies zu
unterNamespace\foo
aufgelöst.
-
Vollständig qualifizierte Namen oder Namen mit globalem Präfixoperator wie
$a = new \aktuellerNamespace\foo();
oder
\aktuellerNamespace\foo::staticmethod();
.
Dies wird immer wörtlich wie der im Code angegebene Name verstanden, also
aktuellerNamespace\foo
.
Hier ein Beispiel für die drei Schreibweisen in tatsächlichem Code:
Beachten Sie, dass für den Zugriff auf jede globale Klasse, Funktion oder
Konstante9 auch ein vollständig qualifizierter Name verwendet werden kann,
wie z. B. \strlen(), \Exception
oder \INI_ALL
.
Beispiel #1 Zugriff auf globale Klassen, Funktionen und Konstanten aus einem Namespace
<?php
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
$a = \strlen('hi'); // ruft die globale Funktion strlen auf
$b = \INI_ALL; // greift auf die globale Konstante INI_ALL zu
$c = new \Exception('error'); // erzeugt eine Neue Instanz der globalen
// Klasse Exception
?>
richard at richard-sumilang dot com ¶16 years ago
Syntax for extending classes in namespaces is still the same.
Lets call this Object.php:
<?php
namespace com\rsumilang\common;
class Object{
}
?>
And now lets create a class called String that extends object in String.php:
<?php
class String extends com\rsumilang\common\Object{
}
?>
Now if you class String was defined in the same namespace as Object then you don't have to specify a full namespace path:
<?php
namespace com\rsumilang\common;
class String extends Object
{
}
?>
Lastly, you can also alias a namespace name to use a shorter name for the class you are extending incase your class is in seperate namespace:
<?php
namespace com\rsumilang\util;
use com\rsumlang\common as Common;
class String extends Common\Object
{
}
?>
- Richard Sumilang
Anonymous ¶10 years ago
<?php
namespace Foo;
try {
}
catch (Exception as $ex) {
}
?>
Instead use fully qualified name for the exception to catch it
<?php
namespace Foo;
try {
}
catch (\Exception as $ex) {
}
?>
Lukas Z ¶13 years ago
Well variables inside namespaces do not override others since variables are never affected by namespace but always global:
"Although any valid PHP code can be contained within a namespace, only four types of code are affected by namespaces: classes, interfaces, functions and constants. "
Source: "Defining Namespaces"
http://www.php.net/manual/en/language.namespaces.definition.php
tom at tomwardrop dot com ¶12 years ago
It seems the file system analogy only goes so far. One thing that's missing that would be very useful is relative navigation up the namespace chain, e.g.
<?php
namespace MyProject {
class Person {}
}
namespace MyProject\People {
class Adult extends ..\Person {}
}
?>
That would be really nice, especially if you had really deep namespaces. It would save you having to type out the full namespace just to reference a resource one level up.
philip dot preisser at arcor dot de ¶13 years ago
Working with variables can overwrite equal variables in other namespaces
<?php namespace
main
{}
namespace
main\sub1
{
$data = 1;
}
namespace
main\sub2
{
echo $data;$data = 2;
}
namespace
main\sub1
{
echo $data;$data = 1;
}
namespace
{
echo $data;}
?>