(PHP 5 >= 5.3.0, PHP 7, PHP 8)
Avant de discuter de l'utilisation des espaces de noms, il est important de comprendre comment PHP devine quel espace de noms le code utilise. Une analogie simple peut être faite entre les espaces de noms de PHP et un système de fichiers. Il y a trois moyens d'accéder à un fichier dans un système de fichiers :
Un nom relatif de fichier, tel que foo.txt. Cela est résolu
en dossiercourant/foo.txt où dossiercourant est le
dossier de travail. Si le dossier courant est /home/foo,
ce nom se résout en /home/foo/foo.txt.
Un chemin relatif, tel que sous-dossier/foo.txt. Cela se
résout en dossiercourant/sous-dossier/foo.txt.
Un chemin absolu, tel que /main/foo.txt. Cela se résout
en /main/foo.txt.
Un nom sans qualificatif, ou une classe sans préfixe, telle que
$a = new foo(); ou
foo::methodestatique();. Si le namespace courant
est espacedenomscourant, ceci se résout en
espacedenomscourant\foo. Si le namespace est
global, soit encore le namespace sans nom, cela devient foo.
Une mise en garde : les noms sans qualificatif pour les fonctions et les constantes vont être pris dans le namespace global, si la fonction n'est pas définie dans le namespace courant. Voir Utilisation des espaces de noms : retour au namespace global pour les fonctions et les constantes pour plus de détails.
Un nom qualifié, ou une classe préfixée telle que
$a = new sousespacedenoms\foo(); ou
sousespacedenoms\foo::methodestatique();. Si le namespace courant
est espacedenomscourant, cela devient
espacedenomscourant\sousespacedenoms\foo. Si
le code est global, c'est-à-dire le namespace sans nom,
cela devient sousespacedenoms\foo.
Un nom absolu, ou un nom préfixé avec un opérateur global tel que
$a = new \espacedenomscourant\foo(); ou
\espacedenomscourant\foo::methodestatique();. Cela fait toujours
référence au nom littéral spécifié dans le code : espacedenomscourant\foo.
Voici un exemple des trois syntaxes, dans du code réel :
file1.php
<?php
namespace Foo\Bar\sousespacedenoms;
const FOO = 1;
function foo() {}
class foo
{
static function methodestatique() {}
}file2.php
<?php
namespace Foo\Bar;
include 'file1.php';
const FOO = 2;
function foo() {}
class foo
{
static function methodestatique() {}
}
/* nom non qualifié */
foo(); // Devient Foo\Bar\foo
foo::methodestatique(); // Devient Foo\Bar\foo, méthode methodestatique
echo FOO; // Devient la constante Foo\Bar\FOO
/* nom qualifié */
sousespacedenoms\foo(); // Devient la fonction Foo\Bar\sousespacedenoms\foo
sousespacedenoms\foo::methodestatique(); // devient la classe Foo\Bar\sousespacedenoms\foo,
// méthode methodestatique
echo sousespacedenoms\FOO; // Devient la constante Foo\Bar\sousespacedenoms\FOO
/* nom absolu */
\Foo\Bar\foo(); // Devient la fonction Foo\Bar\foo
\Foo\Bar\foo::methodestatique(); // Devient la classe Foo\Bar\foo, méthode methodestatique
echo \Foo\Bar\FOO; // Devient la constante Foo\Bar\FOO
Il est à noter que pour accéder à n'importe quelle classe, fonction ou constante
globale, un nom absolu peut être utilisé, tel que
\strlen() ou \Exception ou
\INI_ALL .
Exemple #1 Accès aux classes, fonctions et constantes globales depuis un espace de noms
<?php
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
print \strlen('hi') . "\n"; // appelle la fonction globale strlen
print \INI_ALL . "\n"; // accès à une constante INI_ALL
$c = new \Exception('error'); // instancie la classe globale Exception
print $c::class . "\n";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<?php
namespace Foo;
try {
// Something awful here
// That will throw a new exception from SPL
}
catch (Exception as $ex) {
// We will never get here
// This is because we are catchin Foo\Exception
}
?>
Instead use fully qualified name for the exception to catch it
<?php
namespace Foo;
try {
// something awful here
// That will throw a new exception from SPL
}
catch (\Exception as $ex) {
// Now we can get here at last
}
?>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 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.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
}
?>