Foire aux questions : ce que vous devez savoir des espaces de noms

Cette FAQ est d�compos�e en deux sections : les questions courantes, et les points particuliers de l'impl�mentation, qui peuvent �tre utile � la compr�hension globale.

D'abord, les questions courantes.

  1. Si je n'utilise pas d'espaces de noms, est-ce que je dois m'en soucier ?
  2. Comment utiliser une classe globale ou interne depuis un espace de noms ?
  3. Comment utiliser les classes d'espaces de noms, les fonctions ou les constantes dans leur propre espace ?
  4. Comment est-ce qu'un nom comme \mon\nom ou \nom est r�solu ?
  5. Comment est-ce qu'un nom tel que mon\nom est r�solu ?
  6. Comment un nom de classe sans qualification, tel que nom, est r�solu ?
  7. Comment une fonction sans qualification ou une constante de nom nom est r�solue ?

Voici les points particuliers de l'impl�mentation, qui peuvent �tre utile � la compr�hension globale.

  1. Les noms import�s ne doivent pas entrer en conflit avec les classes d�finies dans le m�me fichier
  2. Les espaces de noms imbriqu�s sont interdits
  3. Ni les fonctions, ni les constantes ne peuvent �tre import�es avec la commande use
  4. Les noms d'espaces de noms dynamiques doivent prot�ger l'anti-slash
  5. Des constantes ind�finies r�f�renc�es avec un anti-slash produisent une erreur fatale
  6. Impossible de remplacer des constantes sp�ciales comme NULL, TRUE, FALSE, ZEND_THREAD_SAFE ou ZEND_DEBUG_BUILD

Si je n'utilise pas d'espaces de noms, est-ce que je dois m'en soucier ?

Non, les espaces de noms n'affectent pas le code existant, d'une mani�re ou d'une autre, ni le code qui sera produit et qui n'utilise pas les espaces de noms. Vous pouvez �crire ceci si vous voulez :

Exemple #1 Acc�s � une classe globale de l'ext�rieur d'un espace de noms

<?php
$a 
= new \stdClass;

C'est une fonctionnalit� �quivalente � :

Exemple #2 Acc�der � des classes globales hors d'un espace de noms

<?php
$a 
= new stdClass;

Comment utiliser une classe globale ou interne depuis un espace de noms ?

Exemple #3 Acc�s aux classes internes depuis un espace de noms

<?php
namespace foo;
$a = new \stdClass;

function 
test(\ArrayObject $typehintexample null) {}

$a = \DirectoryIterator::CURRENT_AS_FILEINFO;

// extension d'une classe interne ou globale
class MyException extends \Exception {}
?>

Comment utiliser les classes d'espaces de noms, les fonctions ou les constantes dans leur propre espace ?

Exemple #4 Acc�s aux classes, fonctions et constantes internes dans un espace de noms

<?php
namespace foo;

class 
MaClasse {}

// utilisation d'une classe dans l'espace de noms courant, sous forme de type d'argument
function test(MaClasse $typehintexample null) {}

// une autre mani�re d'utiliser une classe dans l'espace de noms courant
function test(\foo\MaClasse $typehintexample null) {}

// extension d'une classe dans l'espace de noms courant
class Extended extends MaClasse {}

// acc�s � une fonction globale
$a = \globalfunc();

// acc�s � une constante globale
$b = \INI_ALL;
?>

Comment est-ce qu'un nom comme \mon\nom ou \nom est r�solu ?

Les noms qui commencent par \ sont toujours r�solus en ce � quoi ils ressemblent, ce qui fait que \mon\nom est en fait mon\nom, et \Exception est Exception.

Exemple #5 Noms d'espaces absolus

<?php
namespace foo;
$a = new \mon\nom(); // instantie la classe "mon\nom"
echo \strlen('hi'); // appelle la fonction "strlen"
$a = \INI_ALL// $a re�oit la valeur de la constante "INI_ALL"
?>

Comment est-ce qu'un nom tel que mon\nom est r�solu ?

Les noms qui contiennent un anti-slash mais ne commencent par par un anti-slash, comme mon\nom peuvent �tre r�solus de deux mani�res diff�rentes.

S'il y a eu une commande d'importation qui fait un alias de mon, alors l'alias import� est appliqu� � la place de mon, et l'espace de noms devient mon\nom.

Sinon, l'espace de noms courant est ajout� avant le chemin de la classe mon\nom.

Exemple #6 Noms qualifi�s

<?php
namespace foo;
use 
blah\blah as foo;

$a = new mon\nom(); // instantie la classe "foo\mon\nom"
foo\bar::name(); // appelle la m�thode statique "name" dans la classe "blah\blah\bar"
mon\bar(); // appelle la fonction "foo\mon\bar"
$a mon\BAR// affecte � $a la valeur de la constante "foo\mon\BAR"
?>

Comment un nom de classe sans qualification, tel que nom, est r�solu ?

Les noms de classes qui ne contiennent pas d'anti-slash comme nom peuvent �tre r�solus de deux mani�res diff�rentes.

S'il y a une instruction d'importation qui d�finit un alias pour nom, alors l'alias est appliqu�.

Sinon, l'espace de noms courant est utilis�, et pr�fix� � nom.

Exemple #7 Classes sans qualification

<?php
namespace foo;
use 
blah\blah as foo;

$a = new nom(); // instantie "foo\nom" class
foo::nom(); // appelle la m�thode statique "nom" dans la classe "blah\blah"
?>

Comment une fonction sans qualification ou une constante de nom nom est r�solue ?

Les fonctions et constantes qui n'ont pas d'anti-slash dans leur nom comme nom sont r�solues de deux mani�res diff�rentes :

D'abord, l'espace de noms courant est pr�fix� � name.

Ensuite, si la constante ou la fonction nom n'existe pas dans l'espace de nom courant, la version globale de la constante ou la fonction nom est utilis�e.

Exemple #8 Fonctions et constantes sans espace de noms

<?php
namespace foo;
use 
blah\blah as foo;

const 
FOO 1;

function 
mon() {}
function 
foo() {}
function 
sort(&$a)
{
    
sort($a);
    
$a array_flip($a);
    return 
$a;
}

mon(); // appelle "foo\mon"
$a strlen('hi'); // appelle la fonction globale "strlen" car "foo\strlen" n'existe pas
$arr = array(1,3,2);
$b sort($arr); // appelle la fonction "foo\sort"
$c foo(); // appelle la fonction "foo\foo" : l'importation n'est pas appliqu�e

$a FOO// assigne � $a la valeur de la constante "foo\FOO" : l'importation n'est pas appliqu�e
$b INI_ALL// assigne � $b la valeur de la constante "INI_ALL"
?>

Les noms import�s ne doivent pas entrer en conflit avec les classes d�finies dans le m�me fichier

La combinaison de script suivante est valide :

file1.php

<?php
namespace mes\trucs;
class 
MaClasse {}
?>

another.php

<?php
namespace another;
class 
untruc {}
?>

file2.php

<?php
namespace mes\trucs;
include 
'file1.php';
include 
'another.php';

use 
another\untruc as MaClasse;
$a = new MaClasse// instantie la classe "untruc" de l'espace de noms another
?>

Il n'y a pas de conflit de noms, m�me si la classe MaClasse existe dans l'espace de noms mes\trucs, car la d�finition de MaClasse est dans un fichier s�par�. Cependant, l'exemple suivant produit une erreur fatale � cause d'un conflit de noms, car MaClasse est d�finie dans le m�me fichier que l'instruction use.

<?php
namespace mes\trucs;
use 
another\untruc as MaClasse;
class 
MaClasse {} // erreur fatale: MaClasse est en conflit avec la commande d'importation
$a = new MaClasse;
?>

Les espaces de noms imbriqu�s sont interdits

PHP ne permet pas d'imbriquer des espaces de noms.

<?php
namespace mes\trucs {
    namespace 
nested {
        class 
foo {}
    }
}
?>

Cependant, il est facile de simuler des espaces de noms imbriqu�s, comme ceci :

<?php
namespace mes\trucs\nested {
    class 
foo {}
}
?>

Ni les fonctions, ni les constantes ne peuvent �tre import�es avec la commande use

Les seuls �l�ments qui sont affect�s par la commande use sont les espaces de noms et les classes. Afin de r�duire le nom d'une constante ou d'une fonction, il faut l'importer dans un espace de noms.

<?php
namespace mine;
use 
ultra\long\ns\nom;

$a nom\CONSTANT;
nom\func();
?>

Les noms d'espaces de noms dynamiques doivent prot�ger l'anti-slash

Il est tr�s important de r�aliser que, comme les anti-slash sont utilis�s comme caract�res de protection dans les cha�nes, il faut toujours les doubler pour pouvoir les utiliser dans une cha�ne. Sinon, il y a un risque d'utilisation inattendue :

Exemple #9 Dangers de l'utilisation des espaces de noms dans une cha�ne

<?php
$a 
= new "dangereux\nom"// \n est une nouvelle ligne dans une cha�ne!
$obj = new $a;

$a = new 'pas\vraiment\dangereux'// aucun problem ici
$obj = new $a;
?>

Dans une cha�ne � double guillemets, la s�quence de protection est beaucoup plus s�curitaire � utiliser, mais il est quand m�me recommand� de toujours prot�ger les anti-slashs dans une cha�ne qui contient un espace de noms.

Des constantes ind�finies r�f�renc�es avec un anti-slash produisent une erreur fatale

Toute constante ind�finie qui est sans qualificatif tel que FOO va produite une alerte : PHP supposait que FOO �tait la valeur de la constante. Toute constante, qualifi�e partiellement ou totalement, qui contient un anti-slash, produite une erreur fatale si ind�finie.

Exemple #10 Constantes ind�finies

<?php
namespace bar;
$a FOO// produit une alerte : constante ind�finie "FOO", qui prend la valeur de "FOO";
$a = \FOO// erreur fatale, constante d'espace de noms ind�finie FOO
$a Bar\FOO// erreur fatale, constante d'espace de noms ind�finie bar\Bar\FOO
$a = \Bar\FOO// erreur fatale, constante d'espace de noms ind�finie Bar\FOO
?>

Impossible de remplacer des constantes sp�ciales comme NULL, TRUE, FALSE, ZEND_THREAD_SAFE ou ZEND_DEBUG_BUILD

Toute tentative dans un espace de noms de remplacer les constantes natives ou sp�ciales engendre une erreur fatale.

Exemple #11 Constantes qui ne peuvent �tre red�finies

<?php
namespace bar;
const 
NULL 0// erreur fatale;
const true 'stupid'// encore une erreur fatale;
// etc.
?>