Namespaces verwenden: Aliase/Importieren

(PHP 5 >= 5.3.0, PHP 7)

Die Möglichkeit, auf vollständig qualifizierte Namen mit einem Alias (Importieren) zuzugreifen, ist ein wichtiges Feature von Namespaces. Dies ist ähnlich wie die Möglichkeit von Unix-basierten Dateisystemen einen symbolischen Link auf eine Datei oder ein Verzeichnis anzulegen.

Alle PHP-Versionen die Namespaces unterstützen drei Arten von Aliasen oder Importen: Einen Alias für einen Klassennamen, einen Alias für einen Interfacenamen und einen Alias für einen Namespace. PHP 5.6+ erlauben ebenfalls den Import bzw. die Vergabe eines Alias für Funktionen und Konstanten.

Ein Alias wird in PHP mittels des use-Operators angelegt. Hier ein Beispiel, welches alle fünf Arten von Importen zeigt:

Beispiel #1 Aliase/Importieren mit dem use-Operator

<?php
namespace foo;
use 
My\Full\Classname as Another;

// dies ist das gleiche wie use My\Full\NSname as NSname
use My\Full\NSname;

// importiert eine globale Klasse
use ArrayObject;

// Eine Funktion importieren (PHP 5.6+)
use function My\Full\functionName;

// Alias für eine Funktion (PHP 5.6+)
use function My\Full\functionName as func;

// Eine Konstante importieren (PHP 5.6+)
use const My\Full\CONSTANT;

$obj = new namespace\Another// erzeugt ein Objekt der Klasse foo\Another
$obj = new Another// erzeugt ein Objekt der Klasse My\Full\Classname
NSname\subns\func(); // ruft die Funktion My\Full\NSname\subns\func auf
$a = new ArrayObject(array(1)); // erzeugt ein Objekt der Klasse ArrayObject
// ohne das "use ArrayObject" wäre ein Objekt der Klasse foo\ArrayObject erzeugt worden
func(); // ruft die Funktion My\Full\functionName auf
echo CONSTANT// Gibt den Wert von My\Full\CONSTANT aus
?>
Beachten Sie, dass für Namen von Namespaces (vollständig qualifizierte Namespacenamen mit einem Namensraumseparator, wie Foo\Bar, im Gegensatz zu globalen Namen ohne Separator, wie FooBar) der führende Backslash nicht notwendig und nicht empfohlen ist, weil importierte Namen vollständig qualifiziert sein müssen und nicht relativ zum aktuellen Namespace verarbeitet werden.

PHP unterstützt zusätzlich auch eine komfortable Kurzsyntax, mit der mehrere use-Ausdrücke in der gleichen Zeile erscheinen können.

Beispiel #2 Aliase/Importieren mit dem use-Operator, mehrere use-Ausdrücke kombiniert

<?php
use My\Full\Classname as AnotherMy\Full\NSname;

$obj = new Another// erzeugt ein Objekt der Klasse My\Full\Classname
NSname\subns\func(); // ruft die Funktion My\Full\NSname\subns\func auf
?>

Importieren wird zur Kompilierungszeit ausgeführt und hat daher keinen Einfluss auf dynamische Klassen-, Funktions- oder Konstantennamen.

Beispiel #3 Importieren und dynamische Namen

<?php
use My\Full\Classname as AnotherMy\Full\NSname;

$obj = new Another// erzeugt ein Objekt der Klasse My\Full\Classname
$a 'Another';
$obj = new $a;      // erzeugt ein Objekt der Klasse Another
?>

Zusätzlich beeinflusst das Importieren nur unqualifizierte und qualifizierte Namen. Vollständig qualifizierte Namen sind absolut und werden von Importen nicht beeinflusst.

Beispiel #4 Importieren und vollständig qualifizierte Namen

<?php
use My\Full\Classname as AnotherMy\Full\NSname;

$obj = new Another// erzeugt ein Objekt der Klasse My\Full\Classname
$obj = new \Another// erzeugt ein Objekt der Klasse Another
$obj = new Another\thing// erzeugt ein Objekt der Klasse My\Full\Classname\thing
$obj = new \Another\thing// erzeugt ein Objekt der Klasse Another\thing
?>

Gültigkeitsbereiche für Importe

Das Schlüsselwort use muss im äußersten Gültigkeitsbereich (dem globalen Gültigkeitsbereich) oder innerhalb einer Namespace-Deklaration angegeben werden. Das ist darin begründet, dass Importe zur Kompilierungszeit und nicht zur Laufzeit durchgeführt werden und daher nicht in einem anderen Gültigkeitsbereich liegen dürfen. Das folgende Beispiel zeigt eine ungültige Verwendung des use-Schlüsselwortes:

Beispiel #5 Ungültige Importregel

<?php
namespace Languages;

function 
toGreenlandic()
{
    use 
Languages\Danish;

    
// ...
}
?>

Hinweis:

Importregeln sind auf Dateibasis gültig, das heißt eine eingebundene Datei wird NICHT die Importregeln der einbindenden Datei erben.

Gruppierte use Deklarationen

Von PHP 7.0 an können Klassen, Funktionen und Konstanten, die aus dem gleichen Namespace importiert werden, in einer einzigen use Anweisung gruppiert werden.

<?php

// Pre PHP 7 Code
use some\namespace\ClassA;
use 
some\namespace\ClassB;
use 
some\namespace\ClassC as C;

use function 
some\namespace\fn_a;
use function 
some\namespace\fn_b;
use function 
some\namespace\fn_c;

use const 
some\namespace\ConstA;
use const 
some\namespace\ConstB;
use const 
some\namespace\ConstC;

// PHP 7+ Code
use some\namespace\{ClassAClassBClassC as C};
use function 
some\namespace\{fn_afn_bfn_c};
use const 
some\namespace\{ConstAConstBConstC};
add a note add a note

User Contributed Notes 16 notes

up
41
k at webnfo dot com
3 years ago
Note that you can not alias global namespace:

use \ as test;

echo test\strlen('');

won't work.
up
3
me at ruslanbes dot com
5 months ago
Note the code `use ns1\c1` may refer to importing class `c1` from namespace `ns1` as well as importing whole namespace `ns1\c1` or even import both of them in one line. Example:

<?php
namespace ns1;

class
c1{}

namespace
ns1\c1;

class
c11{}

namespace
main;

use
ns1\c1;

$c1 = new c1();
$c11 = new c1\c11();

var_dump($c1); // object(ns1\c1)#1 (0) { }
var_dump($c11); // object(ns1\c1\c11)#2 (0) { }
up
21
x at d dot a dot r dot k dot REMOVEDOTSANDTHIS dot gray dot org
3 years ago
You are allowed to "use" the same resource multiple times as long as it is imported under a different alias at each invocation.

For example:

<?php
use Lend;
use
Lend\l1;
use
Lend\l1 as l3;
use
Lend\l2;
use
Lend\l1\Keller;
use
Lend\l1\Keller as Stellar;
use
Lend\l1\Keller as Zellar;
use
Lend\l2\Keller as Dellar;

...

?>

In the above example, "Keller", "Stellar", and "Zellar" are all references to "\Lend\l1\Keller", as are "Lend\l1\Keller", "l1\Keller", and "l3\Keller".
up
19
anon
2 years ago
The <?php use ?> statement does not load the class file. You have to do this with the <?php require ?> statement or by using an autoload function.
up
16
cl
3 years ago
Something that is not immediately obvious, particular with PHP 5.3, is that namespace resolutions within an import are not resolved recursively.  i.e.: if you alias an import and then use that alias in another import then this latter import will not be fully resolved with the former import.

For example:
use \Controllers as C;
use C\First;
use C\Last;

Both the First and Last namespaces are NOT resolved as \Controllers\First or \Controllers\Last as one might intend.
up
6
kelerest123 at gmail dot com
1 year ago
For the fifth example (example #5):

When in block scope, it is not an illegal use of use keyword, because it is used for sharing things with traits.
up
21
c dot 1 at smithies dot org
5 years ago
If you are testing your code at the CLI, note that namespace aliases do not work!

(Before I go on, all the backslashes in this example are changed to percent signs because I cannot get sensible results to display in the posting preview otherwise. Please mentally translate all percent signs henceforth as backslashes.)

Suppose you have a class you want to test in myclass.php:

<?php
namespace my%space;
class
myclass {
// ...
}
?>

and you then go into the CLI to test it. You would like to think that this would work, as you type it line by line:

require 'myclass.php';
use my%space%myclass; // should set 'myclass' as alias for 'my%space%myclass'
$x = new myclass; // FATAL ERROR

I believe that this is because aliases are only resolved at compile time, whereas the CLI simply evaluates statements; so use statements are ineffective in the CLI.

If you put your test code into test.php:
<?php
require 'myclass.php';
use
my%space%myclass;
$x = new myclass;
//...
?>
it will work fine.

I hope this reduces the number of prematurely bald people.
up
6
Anonymous
3 years ago
The last example on this page shows a possibly incorrect attempt of aliasing, but it is totally correct to import a trait \Languages\Languages\Danish.
up
0
dominic_mayers at yahoo dot com
9 days ago
To clarify the distinction between inserting a trait in a class and importing a trait in a namespace, here is an example where we first import and then insert a trait.

<?php
namespace ns1;
trait
T {
  static
$a = "In T";
}

namespace
ns2;
use
ns1\T; // Importing the name of trait ns1\T  in the namespace ns2
class C {
  use
T; // Inserting trait T in the class C, making use of the imported name.


namespace
main;
use
ns2\C;
echo
C::$a; // In T;
up
0
dominic_mayers at yahoo dot com
9 days ago
The keyword "use" has been recycled for three distinct applications:
1- to import/alias classes, traits, constants, etc. in namespaces,
2- to insert traits in classes,
3- to inherit variables in closures.
This page is only about the first application: importing/aliasing. Traits can be inserted in classes, but this is different from importing a trait in a namespace, which cannot be done in a block scope, as pointed out in example 5. This can be confusing, especially since all searches for the keyword "use" are directed to the documentation here on importing/aliasing.
up
1
thinice at gmail.com
5 years ago
Because imports happen at compile time, there's no polymorphism potential by embedding the use keyword in a conditonal.

e.g.:

<?php
if ($objType == 'canine') {
  use
Animal\Canine as Beast;
}
if (
$objType == 'bovine') {
  use
Animal\Bovine as Beast;
}

$oBeast = new Beast;
$oBeast->feed();
?>
up
-1
nsdhami at live dot jp
6 years ago
The "use" keyword can not be declared inside the function or method. It should be declared as global, after the "namespace" as:

<?php

namespace mydir;

// works perfectly
use mydir/subdir/Class1 as Class1;

function
fun1()
{
   
// Parse error: syntax error, unexpected T_USE
   
use mydir/subdir/Class1 as Class1;
}

class
Class2
{
    public function
fun2()
    {
       
// Parse error: syntax error, unexpected T_USE
       
use mydir/subdir/Class1 as Class1;
    }
}
?>
up
-2
samuel dot roze at gmail dot com
4 years ago
(All the backslashes in namespaces are slashes because I can't figure out how to post backslashes here.)

You can have the same "use" for a class and a namespace. For example, if you have these files:

<?php
// foo/bar.php
namespace foo;

class
bar
{
    public function
__toString ()
    {
        return
'foo\bar\__toString()';
    }
}
?>

<?php
// foo/bar/MyClass.php
namespace foo/bar;

class
MyClass
{
    public function
__toString ()
    {
        return
'foo\bar\MyClass\__toString()';
    }
}
?>

In another namespace, you can do:
<?php
namespace another;
require_once
'foo/bar.php';
require_once
'foo/bar/MyClass.php';

use
foo/bar;

$bar = new bar();
echo
$bar."\n";

$class = new bar/MyClass();
echo
$class."\n";
?>

And it will makes the following output:
foo\bar\__toString()
foo\bar\MyClass\__toString()
up
-4
sernuzh at gmail dot com
1 year ago
You'll get here the
Fatal error: Cannot declare class others\name because the name is already in use
So you can't get two classes <name> inside one namespace
<?php
namespace my {
class
name {
public function
__construct(){
echo
'my_namespace_object';
}
}
}
namespace
others{
use
my\name;
class
name {
public function
__construct(){
echo
'others_namespace_object';
}
}
$newObject = new name();
}
?>
up
-18
Jan Tvrdk
5 years ago
Importing and aliasing an interface name is also supported.
up
-22
Dr. Gianluigi &#34;Zane&#34; Zanettini
1 year ago
I was attempting to use something like this:

<?php
use $my_variable_namespace
?>

This is not supported. I did this instead:

<?php
if(..)
    use
My\First\Namespace;
else
    use
My\Other\Namespace;
?>
To Top