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.
- Si je n'utilise pas d'espaces de noms, est-ce que je dois m'en soucier ?
- Comment utiliser une classe globale ou interne depuis un espace de noms ?
- Comment utiliser les classes d'espaces de noms, les fonctions ou les constantes dans leur propre espace ?
- Comment est-ce qu'un nom comme \mon\nom ou \nom est r�solu ?
- Comment est-ce qu'un nom tel que mon\nom est r�solu ?
- Comment un nom de classe sans qualification, tel que nom, est r�solu ?
- 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.
- Les noms import�s ne doivent pas entrer en conflit avec les classes d�finies dans le m�me fichier
- Les espaces de noms imbriqu�s sont interdits
- Ni les fonctions, ni les constantes ne peuvent �tre import�es avec la commande use
- Les noms d'espaces de noms dynamiques doivent prot�ger l'anti-slash
- Des constantes ind�finies r�f�renc�es avec un anti-slash produisent une erreur fatale
- 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.
?>