Files
doc-fr/language/namespaces.xml
Gina Peter Banyard d26f887799 Apply revchecked skipped commit c60943fefc4ff8950460e76d714a463437cf0eb2
Replace PHP_INI_* with INI_* constants
2024-01-26 13:54:28 +00:00

1605 lines
52 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 874f7c1266d4e4f2e1e6c79b5fb48b590caa1197 Maintainer: yannick Status: ready -->
<!-- Reviewed: no -->
<!-- CREDITS: DAnnebicque -->
<chapter xml:id="language.namespaces" xmlns="http://docbook.org/ns/docbook"
version="1.1">
<title>Les espaces de noms</title>
<sect1 xml:id="language.namespaces.rationale">
<title>Introduction aux espaces de noms</title>
<titleabbrev>Introduction</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<simpara>
Que sont les espaces de noms ? Dans leur définition la plus large, ils représentent
un moyen d'encapsuler des éléments. Cela peut être conçu comme un concept
abstrait, pour plusieurs raisons. Par exemple, dans un système de fichiers, les
dossiers représentent un groupe de fichiers associés et servent d'espace de noms
pour les fichiers qu'ils contiennent. Un exemple concret est que le fichier
<literal>foo.txt</literal> peut exister dans les deux dossiers
<literal>/home/greg</literal> et <literal>/home/other</literal>, mais que
les deux copies de <literal>foo.txt</literal> ne peuvent pas co-exister
dans le même dossier. De plus, pour accéder au fichier <literal>foo.txt</literal>
depuis l'extérieur du dossier <literal>/home/greg</literal>, il faut préciser
le nom du dossier en utilisant un séparateur de dossier, tel que
<literal>/home/greg/foo.txt</literal>. Le même principe s'applique aux
espaces de noms dans le monde de la programmation.
</simpara>
<simpara>
Dans le monde PHP, les espaces de noms sont conçus pour résoudre deux problèmes
que rencontrent les auteurs de bibliothèques et d'applications lors de la réutilisation
d'éléments tels que des classes ou des bibliothèques de fonctions :
</simpara>
<para>
<orderedlist>
<listitem>
<simpara>
Collisions de noms entre le code que vous créez, les classes, fonctions
ou constantes internes de PHP, ou celle de bibliothèques tierces.
</simpara>
</listitem>
<listitem>
<simpara>
La capacité de faire des alias ou de raccourcir des Noms_Extremement_Long
pour aider à la résolution du premier problème, et améliorer la lisibilité
du code.
</simpara>
</listitem>
</orderedlist>
</para>
<simpara>
Les espaces de noms PHP fournissent un moyen pour regrouper des classes, interfaces,
fonctions ou constantes. Voici un exemple de syntaxe des espaces de noms PHP :
</simpara>
<example>
<title>Exemple de syntaxe des espaces de noms</title>
<titleabbrev>Espaces de noms</titleabbrev>
<programlisting role="php">
<![CDATA[
<?php
namespace mon\nom; // Voyez la section "Définition des espaces de noms"
class MaClasse {}
function mafonction() {}
const MACONSTANTE = 1;
$a = new MaClasse;
$c = new \mon\nom\MaClasse; // Voyez la section "Espace global"
$a = strlen('bonjour'); // Voyez "Utilisation des espaces de noms : retour
// à l'espace global
$d = namespace\MACONSTANTE; // Voyez "L'opérateur namespace et la constante __NAMESPACE__
$d = __NAMESPACE__ . '\MACONSTANTE';
echo constant($d); // Voyez "Espaces de noms et fonctionnalités dynamiques"
?>
]]>
</programlisting>
</example>
<note>
<simpara>
Les noms d'espaces de noms ne sont pas sensible à la casse.
</simpara>
</note>
<note>
<para>
Les espaces de noms <literal>PHP</literal>, mais aussi les noms composés
commençant par ces noms (comme <literal>PHP\Classes</literal>)
sont réservés pour l'utilisation interne du langage, et ne doivent pas être utilisés
dans le code de l'espace utilisateur.
</para>
</note>
</sect1>
<sect1 xml:id="language.namespaces.definition">
<title>Définition des espaces de noms</title>
<?phpdoc print-version-for="namespaces"?>
<para>
Bien que du code PHP valide puisse être contenu dans un espace de noms,
seuls les types de code suivants peuvent être affectés par les espaces de noms :
les classes (incluant les abstraites et les traits), les interfaces,
les fonctions et les constantes.
</para>
<para>
Les espaces de noms sont déclarés avec le mot-clé <literal>namespace</literal>.
Un fichier contenant un espace de noms doit déclarer l'espace au début
du fichier, avant tout autre code, avec une seule exception : le mot
clé <xref linkend="control-structures.declare" />.
<example>
<title>Déclaration d'un espace de noms</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet;
const CONNEXION_OK = 1;
class Connexion { /* ... */ }
function connecte() { /* ... */ }
?>
]]>
</programlisting>
</example>
<note>
<simpara>
Les nom complètement qualifié (c.à.d. les noms commençant avec un antislash)
ne sont pas autorisé dans les déclarations d'espaces de noms, car de telle
construction sont interprétées comme des expressions d'espace de nom
relatif.
</simpara>
</note>
Le seul élément autorisé avant la déclaration d'espace de noms est la commande
<literal>declare</literal>, pour définir l'encodage du fichier source. De plus,
aucun code non-PHP ne peut précéder la déclaration d'espace de noms, y compris
des espaces :
<example>
<title>Erreur de déclaration d'un espace de noms</title>
<programlisting role="php">
<![CDATA[
<html>
<?php
namespace MonProjet; // erreur fatale : l'espace de noms doit être le premier élément du script
?>
]]>
</programlisting>
</example>
</para>
<para>
De plus, contrairement à d'autres structures PHP, le même espace de noms peut
être défini dans plusieurs fichiers, ce qui permet de scinder le contenu d'un
espace de noms sur plusieurs fichiers.
</para>
</sect1>
<sect1 xml:id="language.namespaces.nested">
<title>Déclaration d'un sous espace de noms</title>
<titleabbrev>Sous espace de noms</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Comme pour les fichiers et les dossiers, les espaces de noms sont aussi
capables de spécifier une hiérarchie d'espaces de noms. Ainsi, un nom d'espace
de noms peut être défini avec ses sous-niveaux :
<example>
<title>Déclaration d'un espace de noms avec hiérarchie</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet\Sous\Niveau;
const CONNEXION_OK = 1;
class Connexion { /* ... */ }
function connecte() { /* ... */ }
?>
]]>
</programlisting>
</example>
Dans l'exemple ci-dessus, la constante <literal>MonProjet\Sous\Niveau\CONNEXION_OK</literal>,
la classe <literal>MonProjet\Sous\Niveau\Connexion</literal> et la fonction
<literal>MonProjet\Sous\Niveau\connecte</literal> sont créées.
</para>
</sect1>
<sect1 xml:id="language.namespaces.definitionmultiple">
<title>Définition de plusieurs espaces de noms dans le même fichier</title>
<titleabbrev>Définition de plusieurs espaces de noms dans le même fichier</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Plusieurs espaces de noms peuvent aussi être déclarés dans le même fichier.
Il y a deux syntaxes autorisées.
</para>
<para>
<example>
<title>Déclaration de plusieurs espaces de noms, syntaxe à combinaison simple</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet;
const CONNEXION_OK = 1;
class Connexion { /* ... */ }
function connecte() { /* ... */ }
namespace AutreProjet;
const CONNEXION_OK = 1;
class Connexion { /* ... */ }
function connecte() { /* ... */ }
?>
]]>
</programlisting>
</example>
</para>
<para>
Cette syntaxe n'est pas recommandée pour combiner des espaces de noms
dans un seul fichier. Au lieu de cela, il est recommandé d'utiliser
la syntaxe à accolades.
</para>
<para>
<example>
<title>Déclaration de plusieurs espaces de noms, syntaxe à accolades</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet {
const CONNEXION_OK = 1;
class Connexion { /* ... */ }
function connecte() { /* ... */ }
}
namespace AutreProjet {
const CONNEXION_OK = 1;
class Connexion { /* ... */ }
function connecte() { /* ... */ }
}
?>
]]>
</programlisting>
</example>
</para>
<para>
Il est fortement recommandé, en tant que pratique de codage, de ne pas mélanger
plusieurs espaces de noms dans le même fichier. L'utilisation recommandée est de
combiner plusieurs scripts PHP dans le même fichier.
</para>
<para>
Pour combiner plusieurs codes sans espaces de noms dans du code avec espace de noms,
seule la syntaxe à accolades est supportée. Le code global doit être encadré par un
espace de noms sans nom, tel que celui-ci :
<example>
<title>Déclaration de plusieurs espaces de noms avec un espace sans nom</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet {
const CONNEXION_OK = 1;
class Connexion { /* ... */ }
function connecte() { /* ... */ }
}
namespace { // code global
session_start();
$a = MonProjet\connecte();
echo MonProjet\Connexion::start();
}
?>
]]>
</programlisting>
</example>
</para>
<para>
Aucun code PHP ne peut exister hors des accolades de l'espace de noms,
sauf pour ouvrir une nouvelle instruction <literal>declare</literal>.
<example>
<title>Déclaration de plusieurs espaces de noms avec un espace sans nom (2)</title>
<programlisting role="php">
<![CDATA[
<?php
declare(encoding='UTF-8');
namespace MonProjet {
const CONNEXION_OK = 1;
class Connexion { /* ... */ }
function connecte() { /* ... */ }
}
namespace { // code global
session_start();
$a = MonProjet\connecte();
echo MonProjet\Connexion::start();
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.basics">
<title>Utilisation des espaces de noms : introduction</title>
<titleabbrev>Introduction</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Avant de discuter de l'utilisation des espaces de noms, il est important de
comprendre comment PHP devine quel espace de noms votre 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 :
<orderedlist>
<listitem>
<simpara>
Un nom relatif de fichier, tel que <literal>foo.txt</literal>. Cela est résolu
en <literal>dossiercourant/foo.txt</literal><literal>dossiercourant</literal> est le
dossier de travail. Si le dossier courant est <literal>/home/foo</literal>,
ce nom se résout en <literal>/home/foo/foo.txt</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Un chemin relatif, tel que <literal>sous-dossier/foo.txt</literal>. Cela se
résout en <literal>dossiercourant/sous-dossier/foo.txt</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Un chemin absolu, tel que <literal>/main/foo.txt</literal>. Cela se résout
en <literal>/main/foo.txt</literal>.
</simpara>
</listitem>
</orderedlist>
Le même principe peut être appliqué aux espaces de noms de PHP.
Par exemple, on peut faire référence à une classe de trois manières :
<orderedlist>
<listitem>
<simpara>
Un nom sans qualificatif, ou une classe sans préfixe, telle que
<literal>$a = new foo();</literal> ou
<literal>foo::methodestatique();</literal>. Si l'espace de noms courant
est <literal>espacedenomscourant</literal>, ceci se résout en
<literal>espacedenomscourant\foo</literal>. Si l'espace de noms est
global, soit encore l'espace de noms sans nom, cela devient <literal>foo</literal>.
</simpara>
<simpara>
Une mise en garde : les noms sans qualificatif pour les fonctions et les
constantes vont être pris dans l'espace de noms global, si la fonction
n'est pas définie dans l'espace de noms courant. Voyez
<link linkend="language.namespaces.fallback">Utilisation des espaces de noms :
retour à l'espace de noms global pour les fonctions et les constantes</link> pour
plus de détails.
</simpara>
</listitem>
<listitem>
<simpara>
Un nom qualifié, ou une classe préfixée telle que
<literal>$a = new sousespacedenoms\foo();</literal> ou
<literal>sousespacedenoms\foo::methodestatique();</literal>. Si l'espace de noms courant
est <literal>espacedenomscourant</literal>, cela devient
<literal>espacedenomscourant\sousespacedenoms\foo</literal>. Si
le code est global, c'est à dire l'espace de noms sans nom,
cela devient <literal>sousespacedenoms\foo</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Un nom absolu, ou un nom préfixé avec un opérateur global tel que
<literal>$a = new \espacedenomscourant\foo();</literal> ou
<literal>\espacedenomscourant\foo::methodestatique();</literal>. Cela fait toujours
référence au nom littéral spécifié dans le code : <literal>espacedenomscourant\foo</literal>.
</simpara>
</listitem>
</orderedlist>
</para>
<para>
Voici un exemple des trois syntaxes, dans du code réel :
<informalexample>
<simpara>file1.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace Foo\Bar\sousespacedenoms;
const FOO = 1;
function foo() {}
class foo
{
static function methodestatique() {}
}
?>
]]>
</programlisting>
<simpara>file2.php</simpara>
<programlisting role="php">
<![CDATA[
<?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
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Notez que pour accéder à n'importe quelle classe, fonction ou constante
globale, un nom absolu peut être utilisé, tel que
<function>\strlen</function> ou <classname>\Exception</classname> ou
\<constant>INI_ALL</constant>.
<example>
<title>Accès aux classes, fonctions et constantes globales depuis un espace de noms</title>
<programlisting role="php">
<![CDATA[
<?php
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
$a = \strlen('hi'); // appel la fonction globale strlen
$b = \INI_ALL; // accès à une constante INI_ALL
$c = new \Exception('error'); // instantie la classe globale Exception
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.dynamic">
<title>Espaces de noms et langage dynamique</title>
<titleabbrev>Espaces de noms et langage dynamique</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
L'implémentation des espaces de noms de PHP est influencée par sa nature dynamique
de langage de programmation. Par conséquent, pour convertir du code tel que le code
de l'exemple suivant, en un espace de noms :
<example>
<title>Accès dynamique aux éléments</title>
<simpara>example1.php:</simpara>
<programlisting role="php">
<![CDATA[
<?php
class classname
{
function __construct()
{
echo __METHOD__,"\n";
}
}
function funcname()
{
echo __FUNCTION__,"\n";
}
const constname = "global";
$a = 'classname';
$obj = new $a; // affiche classname::__construct
$b = 'funcname';
$b(); // affiche funcname
echo constant('constname'), "\n"; // affiche global
?>
]]>
</programlisting>
</example>
Il faut utiliser un nom absolu (le nom de la classe, avec son préfixe d'espace
de noms). Notez qu'il n'y a pas de différence entre un nom absolu et un nom qualifié
dans un nom de classe, de fonction ou de constante dynamique, ce qui fait que l'antislash
initial n'est pas nécessaire.
<example>
<title>Accès dynamique à des espaces de noms</title>
<programlisting role="php">
<![CDATA[
<?php
namespace nomdelespacedenoms;
class classname
{
function __construct()
{
echo __METHOD__,"\n";
}
}
function funcname()
{
echo __FUNCTION__,"\n";
}
const constname = "namespaced";
/* Note que si vous utilisez des guillemets doubles, "\\nomdelespacedenoms\\classname" doit être utilisé */
$a = '\nomdelespacedenoms\classname';
$obj = new $a; // affiche nomdelespacedenoms\classname::__construct
$a = 'nomdelespacedenoms\classname';
$obj = new $a; // affiche aussi nomdelespacedenoms\classname::__construct
$b = 'nomdelespacedenoms\funcname';
$b(); // affiche nomdelespacedenoms\funcname
$b = '\nomdelespacedenoms\funcname';
$b(); // affiche aussi nomdelespacedenoms\funcname
echo constant('\nomdelespacedenoms\constname'), "\n"; // affiche namespaced
echo constant('nomdelespacedenoms\constname'), "\n"; // affiche aussi namespaced
?>
]]>
</programlisting>
</example>
</para>
<para>
Il est recommandé de lire la <link linkend="language.namespaces.faq.quote">note au sujet
de la protection des espaces de noms dans les chaînes</link>.
</para>
</sect1>
<sect1 xml:id="language.namespaces.nsconstants">
<title>La commande namespace et la constante __NAMESPACE__</title>
<titleabbrev>Commande namespace et __NAMESPACE__</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
PHP supporte deux moyens pour accéder de manière abstraite aux éléments
dans l'espace de nom courant, à savoir la constante magique
<constant>__NAMESPACE__</constant> et la commande <literal>namespace</literal>.
</para>
<para>
La valeur de <constant>__NAMESPACE__</constant> est une chaîne qui contient le nom
de l'espace de noms courant. Dans l'espace global, sans nom, elle contient
une chaîne vide.
<example>
<title>Exemple avec __NAMESPACE__, dans un code avec espace de noms</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet;
echo '"', __NAMESPACE__, '"'; // affiche "MonProjet"
?>
]]>
</programlisting>
</example>
<example>
<title>Exemple avec __NAMESPACE__, dans un code avec espace de noms global</title>
<programlisting role="php">
<![CDATA[
<?php
echo '"', __NAMESPACE__, '"'; // affiche ""
?>
]]>
</programlisting>
</example>
La constante <constant>__NAMESPACE__</constant> est utile pour construire
dynamiquement des noms, tels que :
<example>
<title>Utilisation de __NAMESPACE__ pour une construction dynamique de noms</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet;
function get($classname)
{
$a = __NAMESPACE__ . '\\' . $classname;
return new $a;
}
?>
]]>
</programlisting>
</example>
</para>
<para>
La commande <literal>namespace</literal> peut aussi être utilisée pour
demander explicitement un élément de l'espace de noms courant, ou d'un
sous-espace. C'est l'équivalent pour les espaces de noms de l'opérateur
<literal>self</literal> des classes.
<example>
<title>l'opérateur namespace, dans un espace de noms</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet;
use blah\blah as mine; // Voyez "Utilisation des espaces de noms : alias et importation"
blah\mine(); // appelle la fonction MonProjet\blah\mine()
namespace\blah\mine(); // appelle la fonction MonProjet\blah\mine()
namespace\func(); // appelle la fonction MonProjet\func()
namespace\sub\func(); // appelle la fonction MonProjet\sub\func()
namespace\cname::method(); // appelle la méthode statique "method" de la classe MonProjet\cname
$a = new namespace\sub\cname(); // instantie un objet de la classe MonProjet\sub\cname
$b = namespace\CONSTANT; // assigne la valeur de la constante MonProjet\CONSTANT à $b
?>
]]>
</programlisting>
</example>
<example>
<title>l'opérateur namespace, dans l'espace de noms global</title>
<programlisting role="php">
<![CDATA[
<?php
namespace\func(); // appelle la fonction func()
namespace\sub\func(); // appelle la fonction sub\func()
namespace\cname::method(); // appelle la méthode statique "method" de la classe cname
$a = new namespace\sub\cname(); // instantie un objet de la classe sub\cname
$b = namespace\CONSTANT; // assigne la valeur de la constante CONSTANT à $b
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.importing">
<?phpdoc print-version-for="namespaces"?>
<title>Utilisation des espaces de noms : importation et alias</title>
<titleabbrev>Importation et alias</titleabbrev>
<para>
La capacité de faire référence à un nom absolu avec un alias ou en important
un espace de noms est stratégique. C'est un avantage similaire aux liens
symboliques dans un système de fichiers.
</para>
<para>
PHP peut aliaser(/importer) les constantes, fonctions, classes, interfaces,
traits, énumérations et les espaces de noms.
</para>
<para>
Un alias est créé avec l'opérateur <literal>use</literal>.
Voici un exemple qui présente les cinq types d'importation :
<example>
<title>importation et alias avec l'opérateur use</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
use My\Full\Classname as Another;
// Ceci est la même chose que use My\Full\NSname as NSname
use My\Full\NSname;
// importation d'une classe globale
use ArrayObject;
// importation d'une fonction
use function My\Full\functionName;
// alias d'une fonction
use function My\Full\functionName as func;
// importation d'une constante
use const My\Full\CONSTANT;
$obj = new namespace\Another; // instantie un objet de la classe foo\Another
$obj = new Another; // instantie un objet de la classe My\Full\Classname
NSname\subns\func(); // appelle la fonction My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // instantie un objet de la classe ArrayObject
// Sans l'instruction "use ArrayObject" nous aurions instantié un objet de la classe foo\ArrayObject
func(); // Appel la fonction My\Full\functionName
echo CONSTANT; // affiche la valeur de My\Full\CONSTANT
?>
]]>
</programlisting>
</example>
Notez que pour les noms avec chemin (les noms absolus contenant des
séparateurs d'espaces, tels que <literal>Foo\Bar</literal>, par comparaison avec
les noms globaux, tels que <literal>FooBar</literal>, qui n'en contiennent pas),
l'antislash initial n'est pas nécessaire et n'est pas recommandé, car les noms importés
doivent être absolus et ne sont pas résolus relativement à l'espace de noms courant.
</para>
<para>
De plus, PHP supporte des raccourcis pratiques, tels que les commandes use multiples.
<example>
<title>importation et alias multiples avec l'opérateur use</title>
<programlisting role="php">
<![CDATA[
<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // instantie un objet de la classe My\Full\Classname
NSname\subns\func(); // appelle la fonction My\Full\NSname\subns\func
?>
]]>
</programlisting>
</example>
</para>
<para>
L'importation est réalisée à la compilation, ce qui fait que cela n'affecte pas
les classes, fonctions et constantes dynamiques.
<example>
<title>Importation et noms d'espaces dynamiques</title>
<programlisting role="php">
<![CDATA[
<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // instantie un objet de la classe My\Full\Classname
$a = 'Another';
$obj = new $a; // instantie un objet de la classe Another
?>
]]>
</programlisting>
</example>
</para>
<para>
De plus, l'importation n'affecte que les noms sans qualification. Les noms
absolus restent absolus, et inchangés par un import.
<example>
<title>Importation et noms d'espaces absolus</title>
<programlisting role="php">
<![CDATA[
<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // instantie un objet de la classe My\Full\Classname
$obj = new \Another; // instantie un objet de la classe Another
$obj = new Another\untruc; // instantie un objet de la classe My\Full\Classname\untruc
$obj = new \Another\untruc; // instantie un objet de la classe Another\untruc
?>
]]>
</programlisting>
</example>
</para>
<sect2 xml:id="language.namespaces.importing.scope">
<title>Règles de contextes pour l'importation</title>
<para>
Le mot-clé <literal>use</literal> doit être déclaré dans le contexte le plus
externe d'un fichier (le contexte global) ou alors dans les déclarations d'espace
de noms. Ceci car l'importation est effectuée à la compilation et non durant
l'éxecution, donc on ne peut empiler les contextes. L'exemple qui suit montre des
utilisation incorrectes du mot-clé <literal>use</literal>:
</para>
<para>
<example>
<title>Règles d'importation incorrectes</title>
<programlisting role="php">
<![CDATA[
<?php
namespace Languages;
function toGreenlandic
{
use Languages\Danish;
// ...
}
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
Les règles d'importation sont basées sur les fichiers, ce qui signifie que les fichiers
inclus n'hériteront <emphasis>PAS</emphasis> des règles d'importation du fichier parent.
</para>
</note>
</sect2>
<sect2 xml:id="language.namespaces.importing.group">
<title>Déclaration du groupe <literal>use</literal></title>
<para>
Les classes, fonctions et constantes importées depuis
le même &namespace; peuvent être regroupées dans une
seule instruction &use.namespace;.
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
use some\namespace\ClassA;
use some\namespace\ClassB;
use some\namespace\ClassC as C;
use function some\namespace\fn_a;
use function some\namespace\fn_b;
use function some\namespace\fn_c;
use const some\namespace\ConstA;
use const some\namespace\ConstB;
use const some\namespace\ConstC;
// est équivalent ç la déclaration use groupé suivante
use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};
]]>
</programlisting>
</informalexample>
</sect2>
</sect1>
<sect1 xml:id="language.namespaces.global">
<title>Espace de noms global</title>
<titleabbrev>Global</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Sans aucune définition d'espace de noms, toutes les classes et les fonctions
sont placées dans l'espace de noms global : comme en PHP avant que les espaces
de noms aient été introduits. En préfixant un nom avec un antislash
<literal>\</literal>, on peut demander l'utilisation de l'espace de noms
global, même dans un contexte d'espace de noms spécifique.
<example>
<title>Spécification d'espace de noms global</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A\B\C;
/* Cette fonction est A\B\C\fopen */
function fopen() {
/* ... */
$f = \fopen(...); // appel à fopen global
return $f;
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.fallback">
<title>Utilisation des espaces de noms : retour sur l'espace global pour les fonctions et les constantes</title>
<titleabbrev>Retour sur l'espace global</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Dans un espace de noms, lorsque PHP rencontre un nom sans qualification,
que ce soit une classe, une fonction ou une constante, il le résout avec différentes
priorités. Les noms de classes sont toujours résolus avec l'espace de noms courant.
Pour accéder à des classes internes ou à des classes qui ne sont pas dans
un espace de noms, il faut les représenter avec leur nom absolu, tel que :
<example>
<title>Accès aux classes globales depuis un espace de noms</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A\B\C;
class Exception extends \Exception {}
$a = new Exception('hi'); // $a est un objet de la classe A\B\C\Exception
$b = new \Exception('hi'); // $b est un objet de la classe Exception
$c = new ArrayObject; // erreur fatale, classe A\B\C\ArrayObject non trouvée
?>
]]>
</programlisting>
</example>
</para>
<para>
Pour les fonctions et constantes, PHP va aller les chercher dans l'espace
global s'il ne peut les trouver dans l'espace de noms courant.
<example>
<title>Accès aux fonctions et constantes globales dans un espace de noms</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A\B\C;
const E_ERROR = 45;
function strlen($str)
{
return \strlen($str) - 1;
}
echo E_ERROR, "\n"; // affiche "45"
echo INI_ALL, "\n"; // affiche "7" : accès dans l'espace de noms global INI_ALL
echo strlen('hi'), "\n"; // affiche "1"
if (is_array('hi')) { // affiche "n'est pas un tableau"
echo "est un tableau\n";
} else {
echo "n'est pas un tableau\n";
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.rules">
<title>Règles de résolutions de noms</title>
<titleabbrev>Règles de résolutions de noms</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Dans le cadre des règles de résolution, il y a plusieurs définitions importantes :
<variablelist>
<title>Définitions pour les espaces de noms</title>
<varlistentry>
<term>nom non qualifié</term>
<listitem>
<para>
Ceci est un identifiant ne contenant pas un séparateur d'espace de noms.
Par exemple : <literal>Foo</literal>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>nom qualifié</term>
<listitem>
<para>
Ceci est un identifiant contenant un séparateur d'espace de noms.
Par exemple : <literal>Foo\Bar</literal>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Nom absolu</term>
<listitem>
<para>
Ceci est un identifiant qui commence par un séparateur d'espace de noms.
Par exemple : <literal>\Foo\Bar</literal>. L'espace de noms <literal>Foo</literal>
est aussi un nom absolu.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Nom Relatif</term>
<listitem>
<para>
C'est un identifiant commençant par <literal>namespace</literal>, tel que
<literal>namespace\Foo\Bar</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Les noms sont résolus en suivant les règles suivantes :
<orderedlist>
<listitem>
<simpara>
Les noms absolus se traduisent toujours par les noms sans le séparateur de namespace.
Par exemple, <literal>\A\B</literal> se traduit par <literal>A\B</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Tous les noms qui ne sont pas absolus sont traduit avec
le <literal>namespace</literal> remplacé par le namespace courant.
Si le nom apparait dans le namespace global, le préfixe
<literal>namespace\</literal> est retiré. Par exemple <literal>namespace\A</literal>
dans le namespace <literal>X\Y</literal> se traduit par <literal>X\Y\A</literal>.
Le même nom dans le namespace global se traduit par <literal>A</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Pour les noms absolus, le premier segment est traduit
en accord avec la class/namespace de la table d'importation.
Par exemple, si le namespace <literal>A\B\C</literal> est importé comme <literal>C</literal>, le nom <literal>C\D\E</literal> est traduit par <literal>A\B\C\D\E</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Pour les noms absolus, si aucune règle d'import ne
s'applique, le namespace courant est préfixé par le nom.
Par exemple le nom <literal>C\D\E</literal> dans le namespace <literal>A\B</literal>,
est traduit par <literal>A\B\C\D\E</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Pour les noms absolus, le nom est traduit en lien avec la table courante d'importation pour le type de symbol respectif.
Cela signifie qu'un nom ressemblant à une classe est traduit en accord avec la table d'importation des
class/namespace, les noms de fonctions en utilisant la
table d'importation des fonctions, et les constantes en
utilisant la table d'importation des constantes.
Par exemple, après
<literal>use A\B\C;</literal> un usage tel que <literal>new C()</literal> correspond au nom
<literal>A\B\C()</literal>. De la même manière, après <literal>use function A\B\foo;</literal> un usage
tel que <literal>foo()</literal> correspond au nom <literal>A\B\foo</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Pour les noms relatifs, si aucune règle ne s'applique, et que le nom
fait référence à une classe, le namespace courant sert de préfixe.
Par exemple <literal>new C()</literal> dans le namespace
<literal>A\B</literal> correspond au nom <literal>A\B\C</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
pour les noms relatifs, si aucune règle ne s'applique, et que le nom
fait référence à une fonction ou une constante, et que le code est en
dehors du namespace global, the nom est résolu par l'exécution.
Supposons que le code est dans le namespace
<literal>A\B</literal>, voici comme un appel à la fonction <literal>foo()</literal> est résolu :
</simpara>
<orderedlist>
<listitem>
<simpara>
Il recherche une fonction dans l'espace de noms courant :
<literal>A\B\foo()</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Il essaie de trouver et appeler la fonction <emphasis>globale</emphasis>
<literal>foo()</literal>.
</simpara>
</listitem>
</orderedlist>
</listitem>
</orderedlist>
</para>
<example>
<title>Exemples de résolutions d'espaces de noms</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A;
use B\D, C\E as F;
// appels de fonctions
foo(); // tente d'appeler la fonction "foo" dans l'espace de noms "A"
// puis appelle la fonction globale "foo"
\foo(); // appelle la fonction "foo" définie dans l'espace de noms global
my\foo(); // appelle la fonction "foo" définie dans l'espace de noms "A\my"
F(); // tente d'appeler la fonction "F" définie dans l'espace "A"
// puis tente d'appeler la fonction globale "F"
// référence de classes references
new B(); // crée un objet de la classe "B" définie dans l'espace de noms "A"
// si non trouvé, il essaie l'autochargement sur la classe "A\B"
new D(); // crée un objet de la classe "D" définie dans l'espace de noms "B"
// si non trouvé, il essaie l'autochargement sur la classe "B\D"
new F(); // crée un objet de la classe "E" définie dans l'espace de noms "C"
// si non trouvé, il essaie l'autochargement sur la classe "C\E"
new \B(); // crée un objet de la classe "B" définie dans l'espace de noms global
// si non trouvé, il essaie l'autochargement sur la classe "B"
new \D(); // crée un objet de la classe "D" définie dans l'espace de noms global
// si non trouvé, il essaie l'autochargement sur la classe "D"
new \F(); // crée un objet de la classe "F" définie dans l'espace de noms global
// si non trouvé, il essaie l'autochargement sur la classe "F"
// méthodes statiques et fonctions d'espace de noms d'un autre espace
B\foo(); // appelle la fonction "foo" de l'espace de noms "A\B"
B::foo(); // appelle la méthode "foo" de la classe "B" définie dans l'espace de noms "A"
// si la classe "A\B" n'est pas trouvée, il essaie l'autochargement sur la classe "A\B"
D::foo(); // appelle la méthode "foo" de la classe "D" définie dans l'espace de noms "B"
// si la classe "B\D" n'est pas trouvée, il essaie l'autochargement sur la classe "B\D"
\B\foo(); // appelle la fonction "foo" de l'espace de noms "B"
\B::foo(); // appelle la méthode "foo" de la classe "B" située dans l'espace de noms global
// si la classe "B" n'est pas trouvée, il essaie l'autochargement sur la classe "B"
// méthodes statiques et fonctions d'espace de noms de l'espace courant
A\B::foo(); // appelle la méthode "foo" de la classe "B" de l'espace de noms "A\A"
// si la classe "A\A\B" n'est pas trouvée, il essaie l'autochargement sur la classe "A\A\B"
\A\B::foo(); // appelle la méthode "foo" de la classe "B" de l'espace de noms "A"
// si la classe "A\B" n'est pas trouvée, il essaie l'autochargement sur la classe "A\B"
?>
]]>
</programlisting>
</example>
</sect1>
<sect1 xml:id="language.namespaces.faq">
<title>Foire aux questions : ce que vous devez savoir des espaces de noms</title>
<titleabbrev>Foire aux questions</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
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.
</para>
<para>
D'abord, les questions courantes.
<orderedlist>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.shouldicare">Si je n'utilise pas d'espaces
de noms, est-ce que je dois m'en soucier ?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.globalclass">Comment utiliser une classe
globale ou interne depuis un espace de noms ?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.innamespace">Comment utiliser les classes
d'espaces de noms, les fonctions ou les constantes dans leur propre espace ? </link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.full">
Comment est-ce qu'un nom comme <literal>\mon\nom</literal> ou
<literal>\nom</literal> est résolu ?
</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.qualified">Comment est-ce qu'un nom
tel que <literal>mon\nom</literal> est résolu ?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.shortname1">Comment un nom de classe
sans qualification, tel que <literal>nom</literal>, est résolu ?</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.shortname2">Comment une fonction sans
qualification ou une constante de nom <literal>nom</literal> est résolue ?</link>
</simpara>
</listitem>
</orderedlist>
</para>
<para>
Voici les points particuliers de l'implémentation, qui peuvent être
utiles à la compréhension globale.
<orderedlist>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.conflict">Les noms importés ne doivent
pas entrer en conflit avec les classes définies dans le même fichier</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.nested">Les espaces de noms imbriqués
sont interdits</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.quote">Les noms d'espaces de noms
dynamiques doivent protéger l'antislash</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.constants">Des constantes indéfinies
référencées avec un antislash produisent une erreur fatale</link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="language.namespaces.faq.builtinconst">Impossible de remplacer
des constantes spéciales comme &null;, &true; ou &false;</link>
</simpara>
</listitem>
</orderedlist>
</para>
<sect2 xml:id="language.namespaces.faq.shouldicare">
<title>Si je n'utilise pas d'espaces de noms, est-ce que je dois m'en soucier ?</title>
<para>
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 :
</para>
<para>
<example>
<title>Accès à une classe globale de l'extérieur d'un espace de noms</title>
<programlisting role="php">
<![CDATA[
<?php
$a = new \stdClass;
?>
]]>
</programlisting>
</example>
</para>
<para>
C'est une fonctionnalité équivalente à :
</para>
<para>
<example>
<title>Accéder à des classes globales hors d'un espace de noms</title>
<programlisting role="php">
<![CDATA[
<?php
$a = new stdClass;
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.globalclass">
<title>Comment utiliser une classe globale ou interne depuis un espace de noms ?</title>
<para>
<example>
<title>Accès aux classes internes depuis un espace de noms</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
$a = new \stdClass;
function test(\ArrayObject $parameter_type_example = null) {}
$a = \DirectoryIterator::CURRENT_AS_FILEINFO;
// extension d'une classe interne ou globale
class MyException extends \Exception {}
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.innamespace">
<title>
Comment utiliser les classes d'espaces de noms, les fonctions ou
les constantes dans leur propre espace ?
</title>
<para>
<example>
<title>Accès aux classes, fonctions et constantes internes dans un espace de noms</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
class MaClasse {}
// utilisation d'une classe dans l'espace de noms courant, sous forme de type de paramètre
function test(MaClasse $parameter_type_example = null) {}
// une autre manière d'utiliser une classe dans l'espace de noms courant comme type de paramètre
function test(\foo\MaClasse $parameter_type_example = 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;
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.full">
<title>
Comment est-ce qu'un nom comme <literal>\mon\nom</literal> ou
<literal>\nom</literal> est résolu ?
</title>
<para>
Les noms qui commencent par <literal>\</literal> sont toujours résolus en ce
à quoi ils ressemblent, ce qui fait que <literal>\mon\nom</literal> est en fait
<literal>mon\nom</literal>, et <literal>\Exception</literal> est
<literal>Exception</literal>.
<example>
<title>Noms d'espaces absolus</title>
<programlisting role="php">
<![CDATA[
<?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"
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.qualified">
<title>Comment est-ce qu'un nom tel que <literal>mon\nom</literal> est résolu ?</title>
<para>
Les noms qui contiennent un antislash mais ne commencent par par un
antislash, comme <literal>mon\nom</literal> peuvent être résolus de deux manières
différentes.
</para>
<para>
S'il y a eu une commande d'importation qui fait un alias de
<literal>mon</literal>, alors l'alias importé est appliqué à la place
de <literal>mon</literal>, et l'espace de noms devient <literal>mon\nom</literal>.
</para>
<para>
Sinon, l'espace de noms courant est ajouté avant le chemin de la classe
<literal>mon\nom</literal>.
</para>
<para>
<example>
<title>Noms qualifiés</title>
<programlisting role="php">
<![CDATA[
<?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"
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.shortname1">
<title>Comment un nom de classe
sans qualification, tel que <literal>nom</literal>, est résolu ?</title>
<para>
Les noms de classes qui ne contiennent pas d'antislash comme
<literal>nom</literal> peuvent être résolus de deux manières différentes.
</para>
<para>
S'il y a une instruction d'importation qui définit un alias pour <literal>nom</literal>,
alors l'alias est appliqué.
</para>
<para>
Sinon, l'espace de noms courant est utilisé et préfixé à
<literal>nom</literal>.
</para>
<para>
<example>
<title>Classes sans qualification</title>
<programlisting role="php">
<![CDATA[
<?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"
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.shortname2">
<title>
Comment une fonction sans qualification ou une constante
de nom <literal>nom</literal> est résolue ?
</title>
<para>
Les fonctions et constantes qui n'ont pas d'antislash dans leur nom
comme <literal>nom</literal> sont résolues de deux manières différentes :
</para>
<para>
D'abord, l'espace de noms courant est préfixé à <literal>nom</literal>.
</para>
<para>
Ensuite, si la constante ou la fonction <literal>nom</literal> n'existe pas
dans l'espace de nom courant, la version globale de la constante ou la
fonction <literal>nom</literal> est utilisée.
</para>
<para>
<example>
<title>Fonctions et constantes sans espace de noms</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
use blah\blah as foo;
const FOO = 1;
function mon() {}
function foo() {}
function sort(&$a)
{
\sort($a); // Appel de la fonction globale "sort"
$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"
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.conflict">
<title>Les noms importés ne doivent
pas entrer en conflit avec les classes définies dans le même fichier</title>
<para>
La combinaison de scripts suivante est valide :
<informalexample>
<simpara>file1.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace mes\trucs;
class MaClasse {}
?>
]]>
</programlisting>
<simpara>another.php</simpara>
<programlisting role="php">
<![CDATA[
<?php
namespace another;
class untruc {}
?>
]]>
</programlisting>
<simpara>file2.php</simpara>
<programlisting role="php">
<![CDATA[
<?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
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Il n'y a pas de conflit de noms, même si la classe <literal>MaClasse</literal> existe
dans l'espace de noms <literal>mes\trucs</literal>, car la définition de
<literal>MaClasse</literal> est dans un fichier séparé. Cependant, l'exemple
suivant produit une erreur fatale à cause d'un conflit de noms, car
<literal>MaClasse</literal> est définie dans le même fichier que l'instruction
<literal>use</literal>.
<informalexample>
<programlisting role="php">
<![CDATA[
<?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;
?>
]]>
</programlisting>
</informalexample>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.nested">
<title>Les espaces de noms imbriqués sont interdits</title>
<para>
PHP ne permet pas d'imbriquer des espaces de noms.
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
namespace mes\trucs {
namespace nested {
class foo {}
}
}
?>
]]>
</programlisting>
</informalexample>
Cependant, il est facile de simuler des espaces de noms imbriqués,
comme ceci :
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
namespace mes\trucs\nested {
class foo {}
}
?>
]]>
</programlisting>
</informalexample>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.quote">
<title>Les noms d'espaces de noms dynamiques doivent protéger l'antislash</title>
<para>
Il est très important de réaliser que, comme les antislash 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 :
<example>
<title>Dangers de l'utilisation des espaces de noms dans une chaîne</title>
<programlisting role="php">
<![CDATA[
<?php
$a = "dangereux\nom"; // \n est une nouvelle ligne dans une chaîne!
$obj = new $a;
$a = 'pas\vraiment\dangereux'; // aucun problème ici
$obj = new $a;
?>
]]>
</programlisting>
</example>
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 antislashs dans une chaîne qui contient un espace de noms.
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.constants">
<title>Des constantes indéfinies référencées avec un antislash produisent une erreur fatale</title>
<para>
Toute constante indéfinie qui est sans qualificatif telle que
<literal>FOO</literal> va produite une alerte : PHP supposait que
<literal>FOO</literal> était la valeur de la constante. Toute constante,
qualifiée partiellement ou totalement, qui contient un antislash,
produite une erreur fatale si indéfinie.
<example>
<title>Constantes indéfinies</title>
<programlisting role="php">
<![CDATA[
<?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
?>
]]>
</programlisting>
</example>
</para>
</sect2>
<sect2 xml:id="language.namespaces.faq.builtinconst">
<title>Impossible de remplacer des constantes spéciales comme &null;, &true; ou &false;</title>
<para>
Toute tentative dans un espace de noms de remplacer les constantes
natives ou spéciales, engendre une erreur fatale.
<example>
<title>Constantes qui ne peuvent être redéfinies</title>
<programlisting role="php">
<![CDATA[
<?php
namespace bar;
const NULL = 0; // erreur fatale;
const true = 'stupid'; // encore une erreur fatale;
// etc.
?>
]]>
</programlisting>
</example>
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->