mirror of
https://github.com/php/doc-fr.git
synced 2026-03-24 07:02:06 +01:00
1605 lines
52 KiB
XML
1605 lines
52 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- EN-Revision: 1651836ff309efd14a795eff44ee51455f66c7d3 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 créé, les classes, fonctions
|
|
ou constantes internes de PHP, ou celles 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 sensibles à 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, les traits et les enums), 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 noms complètement qualifiés (c.-à-d. les noms commençant avec un antislash)
|
|
ne sont pas autorisés dans les déclarations d'espaces de noms, car de telles
|
|
constructions sont interprétées comme des expressions d'espace de noms
|
|
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 : le namespace 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 du namespace,
|
|
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 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 :
|
|
<orderedlist>
|
|
<listitem>
|
|
<simpara>
|
|
Un nom relatif de fichier, tel que <literal>foo.txt</literal>. Cela est résolu
|
|
en <literal>dossiercourant/foo.txt</literal> où <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 le namespace courant
|
|
est <literal>espacedenomscourant</literal>, ceci se résout en
|
|
<literal>espacedenomscourant\foo</literal>. Si le namespace est
|
|
global, soit encore le namespace 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 le namespace global, si la fonction
|
|
n'est pas définie dans le namespace courant. Voir
|
|
<link linkend="language.namespaces.fallback">Utilisation des espaces de noms :
|
|
retour au namespace 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 le namespace courant
|
|
est <literal>espacedenomscourant</literal>, cela devient
|
|
<literal>espacedenomscourant\sousespacedenoms\foo</literal>. Si
|
|
le code est global, c'est-à-dire le namespace 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>
|
|
Il est à noter 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). Il est à noter 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 noms 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
|
|
du namespace 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 du namespace 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 le namespace 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>
|
|
Il est à noter 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 au namespace 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'exécution, donc on ne peut empiler les contextes. L'exemple qui suit montre des
|
|
utilisations 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ée 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 le namespace 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 du namespace
|
|
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 le namespace 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 le namespace 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 le namespace 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>. le namespace <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 traduits avec
|
|
le <literal>namespace</literal> remplacé par le namespace courant.
|
|
Si le nom apparaît 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, le nom est résolu par l'exécution.
|
|
Supposons que le code est dans le namespace
|
|
<literal>A\B</literal>, voici comment un appel à la fonction <literal>foo()</literal> est résolu :
|
|
</simpara>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<simpara>
|
|
Il recherche une fonction dans le namespace 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 le namespace "A"
|
|
// puis appelle la fonction globale "foo"
|
|
|
|
\foo(); // appelle la fonction "foo" définie dans le namespace global
|
|
|
|
my\foo(); // appelle la fonction "foo" définie dans le namespace "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 le namespace "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 le namespace "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 le namespace "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 le namespace 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 le namespace 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 le namespace 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" du namespace "A\B"
|
|
|
|
B::foo(); // appelle la méthode "foo" de la classe "B" définie dans le namespace "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 qu'il faut 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. Il est possible d'écrire ceci :
|
|
</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 pas 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 noms 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 à guillemets simples, la séquence de protection est beaucoup plus
|
|
sûre à utiliser, mais il est quand même recommandé de toujours protéger
|
|
les antislashs dans toutes les chaînes comme bonne pratique.
|
|
</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 produire 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,
|
|
produit 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
|
|
-->
|