PHP 5.6.0 released

Namespaces verwenden: Grundlagen

(PHP 5 >= 5.3.0)

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:

  1. 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.
  2. Relative Pfade wie unterVerzeichnis/foo.txt. Dies wird zu aktuellesVerzeichnis/unterVerzeichnis/foo.txt aufgelöst.
  3. 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:
  1. 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.
  2. 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.
  3. 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:

file1.php

<?php
namespace Foo\Bar\subnamespace;

const 
FOO 1;
function 
foo() {}
class 
foo
{
    static function 
staticmethod() {}
}
?>

file2.php

<?php
namespace Foo\Bar;
include 
'file1.php';

const 
FOO 2;
function 
foo() {}
class 
foo
{
    static function 
staticmethod() {}
}

/* Unqualifizierter Name */
foo(); // wird als Funktion Foo\Bar\foo aufgelöst
foo::staticmethod(); // wird als Klasse Foo\Bar\foo und Methode staticmethod aufgelöst
echo FOO// gibt die Konstante Foo\Bar\FOO aus

/* Qualifizierter Name */
subnamespace\foo(); // wird als Funktion Foo\Bar\subnamespace\foo aufgelöst
subnamespace\foo::staticmethod(); // wird als Klasse Foo\Bar\subnamespace\foo und
                                  // Methode staticmethod aufgelöst
echo subnamespace\FOO// gibt die Konstante Foo\Bar\subnamespace\FOO aus

/* Vollständig qualifizierter Name */
\Foo\Bar\foo(); // wird als Funktion Foo\Bar\foo aufgelöst
\Foo\Bar\foo::staticmethod(); // wird als Klasse Foo\Bar\foo und Methode staticmethod aufgelöst
echo \Foo\Bar\FOO// gibt die Konstante Foo\Bar\FOO aus
?>

Beachten Sie, dass für den Zugriff auf jede globale Klasse, Funktion oder Konstante 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
?>

add a note add a note

User Contributed Notes 7 notes

up
50
richard at richard-sumilang dot com
6 years ago
Syntax for extending classes in namespaces is still the same.

Lets call this Object.php:

<?php

namespace com\rsumilang\common;

class
Object{
  
// ... code ...
}

?>

And now lets create a class called String that extends object in String.php:

<?php

class String extends com\rsumilang\common\Object{
  
// ... code ...
}

?>

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
{
  
// ... code ...
}

?>

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
{
  
// ... code ...
}

?>

- Richard Sumilang
up
16
Lukas Z
2 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
up
6
philip dot preisser at arcor dot de
3 years ago
Working with variables can overwrite equal variables in other namespaces

<?php // php5 - package-version : 5.3.5-1ubuntu7.2

   
namespace
   
main
   
{}

    namespace
   
main\sub1
   
{
       
$data = 1;
    }

    namespace
   
main\sub2
   
{
        echo
$data;// 1
       
$data = 2;
    }

    namespace
   
main\sub1
   
{
        echo
$data;// 2
       
$data = 1;
    }

    namespace
    {
        echo
$data;// 1
   
}

?>
up
3
Franois Vespa
3 years ago
It seems you cannot nest a constant declaration within a if statement

<?php

namespace FOO;

if(eval)
const
BAR=true;

// will throw the following error:
// PHP Parse error:  syntax error, unexpected T_CONST

// instead use:

if(eval)
define('FOO\BAR',true);

?>
up
3
tom at tomwardrop dot com
2 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.
up
-9
kukoman at pobox dot sk
5 years ago
PHP 5.3.0alpha2 (cli)
<?php
//  namespace MyProject\DB;
require 'db.php';

use
MyProject\DB; // fine; same as DB\
use MyProject\DB\Connection as DBC; // fine
use MyProject\DB as HM; // fine
use HM\Connection as DBC2; // class call ends with FATAL!!!

$x = new DBC(); // fine
$y = new HM\Connection(); // fine
$z = new DBC2(); // Fatal error: Class 'HM\Connection' not found
?>
up
-6
anon
7 months ago
The namespace hierarchy will normally mirror the directory hierarchy where the class files are located, but this is not a strict requirement. You could, for example, have several class flles with different namespaces in the same directory.
To Top