-
Notifications
You must be signed in to change notification settings - Fork 151
/
namespaces.xml
1604 lines (1503 loc) · 52.4 KB
/
namespaces.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?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> 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 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.