(PHP 5 >= 5.3.0)
Cette FAQ est décomposée en deux sections : les questions courantes, et les points particuliers de l'implémentation, qui peuvent être utiles à la compréhension globale.
D'abord, les questions courantes.
Voici les points particuliers de l'implémentation, qui peuvent être utiles à la compréhension globale.
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;
?>
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 {}
?>
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;
?>
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"
?>
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"
?>
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 la classe "foo\nom"
foo::nom(); // appelle la méthode statique "nom" dans la classe "blah\blah"
?>
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é à nom.
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"
?>
La combinaison de scripts 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;
?>
PHP ne permet pas d'imbriquer des espaces de noms.
<?php
namespace mes\trucs {
namespace nested {
class foo {}
}
}
?>
<?php
namespace mes\trucs\nested {
class foo {}
}
?>
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();
?>
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 problème ici
$obj = new $a;
?>
Toute constante indéfinie qui est sans qualificatif telle 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
?>
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.
?>