-
Notifications
You must be signed in to change notification settings - Fork 59
Expand file tree
/
Copy pathnamespaces.xml
More file actions
1598 lines (1497 loc) · 52 KB
/
namespaces.xml
File metadata and controls
1598 lines (1497 loc) · 52 KB
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: 1651836ff309efd14a795eff44ee51455f66c7d3 Maintainer: PhilDaiguille Status: ready -->
<!-- Reviewed: no -->
<!-- CREDITS: DAnnebicque -->
<chapter xml:id="language.namespaces" xmlns="http://docbook.org/ns/docbook"
version="1.1">
<title>Los espacios de nombres</title>
<sect1 xml:id="language.namespaces.rationale">
<title>Introducción a los espacios de nombres</title>
<titleabbrev>Introducción</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<simpara>
¿Qué son los espacios de nombres? En su definición más amplia, representan
un medio para encapsular elementos. Esto puede concebirse como un concepto
abstracto, por varias razones. Por ejemplo, en un sistema de archivos, los
directorios representan un grupo de archivos asociados y sirven como espacio de nombres
para los archivos que contienen. Un ejemplo concreto es que el archivo
<literal>foo.txt</literal> puede existir en ambos directorios
<literal>/home/greg</literal> y <literal>/home/other</literal>, pero que
las dos copias de <literal>foo.txt</literal> no pueden coexistir
en el mismo directorio. Además, para acceder al archivo <literal>foo.txt</literal>
desde fuera del directorio <literal>/home/greg</literal>, es necesario especificar
el nombre del directorio utilizando un separador de directorios, como
<literal>/home/greg/foo.txt</literal>. El mismo principio se aplica a los
espacios de nombres en el mundo de la programación.
</simpara>
<simpara>
En el mundo de PHP, los espacios de nombres están diseñados para resolver dos problemas
que enfrentan los autores de bibliotecas y aplicaciones al reutilizar elementos
como clases o bibliotecas de funciones:
</simpara>
<para>
<orderedlist>
<listitem>
<simpara>
Colisiones de nombres entre el código que se crea, las clases, funciones
o constantes internas de PHP, o las de bibliotecas de terceros.
</simpara>
</listitem>
<listitem>
<simpara>
La capacidad de crear alias o acortar nombres como Nombres_Extremadamente_Largos
para ayudar a resolver el primer problema y mejorar la legibilidad
del código.
</simpara>
</listitem>
</orderedlist>
</para>
<simpara>
Los espacios de nombres de PHP proporcionan un medio para agrupar clases, interfaces,
funciones o constantes. Aquí hay un ejemplo de sintaxis de los espacios de nombres de PHP:
</simpara>
<example>
<title>Ejemplo de sintaxis de espacios de nombres</title>
<titleabbrev>Espacios de nombres</titleabbrev>
<programlisting role="php">
<![CDATA[
<?php
namespace mon\nom; // Ver la sección "Definición de espacios de nombres"
class MaClasse {}
function mafonction() {}
const MACONSTANTE = 1;
$a = new MaClasse;
$c = new \mon\nom\MaClasse; // Ver la sección "Espacio global"
$a = strlen('bonjour'); // Ver "Uso de espacios de nombres: retorno al espacio global
$d = namespace\MACONSTANTE; // Ver "El operador namespace y la constante __NAMESPACE__
$d = __NAMESPACE__ . '\MACONSTANTE';
echo constant($d); // Ver "Espacios de nombres y características dinámicas"
?>
]]>
</programlisting>
</example>
<note>
<simpara>
Los nombres de espacios de nombres no son sensibles a mayúsculas/minúsculas.
</simpara>
</note>
<note>
<para>
Los espacios de nombres <literal>PHP</literal>, así como los nombres compuestos
que comienzan con estos nombres (como <literal>PHP\Classes</literal>)
están reservados para el uso interno del lenguaje y no deben usarse
en el código del espacio de usuario.
</para>
</note>
</sect1>
<sect1 xml:id="language.namespaces.definition">
<title>Definición de espacios de nombres</title>
<?phpdoc print-version-for="namespaces"?>
<para>
Aunque el código PHP válido puede contenerse en un espacio de nombres,
solo los siguientes tipos de código pueden verse afectados por los espacios de nombres:
las clases (incluyendo las abstractas, los traits y los enums), las interfaces,
las funciones y las constantes.
</para>
<para>
Los espacios de nombres se declaran con la palabra clave <literal>namespace</literal>.
Un archivo que contiene un espacio de nombres debe declarar el espacio al principio
del archivo, antes de cualquier otro código, con una sola excepción: la palabra
clave <xref linkend="control-structures.declare" />.
<example>
<title>Declaración de un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet;
const CONNEXION_OK = 1;
class Connexion { /* ... */ }
function connecte() { /* ... */ }
?>
]]>
</programlisting>
</example>
<note>
<simpara>
Los nombres completamente calificados (es decir, los nombres que comienzan con un backslash)
no están autorizados en las declaraciones de espacios de nombres, ya que tales
construcciones se interpretan como expresiones de espacio de nombres relativo.
</simpara>
</note>
El único elemento autorizado antes de la declaración de espacio de nombres es la instrucción
<literal>declare</literal>, para definir la codificación del archivo fuente. Además,
ningún código no-PHP puede preceder a la declaración de espacio de nombres, incluyendo
espacios:
<example>
<title>Error de declaración de un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<html>
<?php
namespace MonProjet; // error fatal: el espacio de nombres debe ser el primer elemento del script
?>
]]>
</programlisting>
</example>
</para>
<para>
Además, a diferencia de otras estructuras de PHP, el mismo espacio de nombres puede
definirse en varios archivos, lo que permite dividir el contenido de un
espacio de nombres en varios archivos.
</para>
</sect1>
<sect1 xml:id="language.namespaces.nested">
<title>Declaración de un subespacio de nombres</title>
<titleabbrev>Subespacio de nombres</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Al igual que con los archivos y los directorios, los espacios de nombres también
son capaces de especificar una jerarquía de espacios de nombres. Por lo tanto,
un nombre de espacio de nombres puede definirse con sus subniveles:
<example>
<title>Declaración de un espacio de nombres con jerarquía</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet\Sous\Niveau;
const CONNEXION_OK = 1;
class Connexion { /* ... */ }
function connecte() { /* ... */ }
?>
]]>
</programlisting>
</example>
En el ejemplo anterior, se crean la constante <literal>MonProjet\Sous\Niveau\CONNEXION_OK</literal>,
la clase <literal>MonProjet\Sous\Niveau\Connexion</literal> y la función
<literal>MonProjet\Sous\Niveau\connecte</literal>.
</para>
</sect1>
<sect1 xml:id="language.namespaces.definitionmultiple">
<title>Definición de varios espacios de nombres en el mismo archivo</title>
<titleabbrev>Definición de varios espacios de nombres en el mismo archivo</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
También pueden declararse varios espacios de nombres en el mismo archivo.
Hay dos sintaxis autorizadas.
</para>
<para>
<example>
<title>Declaración de varios espacios de nombres, sintaxis de combinación 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>
Esta sintaxis no se recomienda para combinar espacios de nombres
en un solo archivo. En su lugar, se recomienda utilizar
la sintaxis de llaves.
</para>
<para>
<example>
<title>Declaración de varios espacios de nombres, sintaxis de llaves</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>
Se recomienda encarecidamente, como práctica de codificación, no mezclar
varios espacios de nombres en el mismo archivo. El uso recomendado es combinar
varios scripts PHP en el mismo archivo.
</para>
<para>
Para combinar varios códigos sin espacios de nombres en código con espacio de nombres,
solo se admite la sintaxis de llaves. El código global debe estar encerrado por un
espacio de nombres sin nombre, como este:
<example>
<title>Declaración de varios espacios de nombres con un espacio sin nombre</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet {
const CONNEXION_OK = 1;
class Connexion { /* ... */ }
function connecte() { /* ... */ }
}
namespace { // código global
session_start();
$a = MonProjet\connecte();
echo MonProjet\Connexion::start();
}
?>
]]>
</programlisting>
</example>
</para>
<para>
No puede existir ningún código PHP fuera de las llaves del espacio de nombres,
excepto para abrir una nueva instrucción <literal>declare</literal>.
<example>
<title>Declaración de varios espacios de nombres con un espacio sin nombre (2)</title>
<programlisting role="php">
<![CDATA[
<?php
declare(encoding='UTF-8');
namespace MonProjet {
const CONNEXION_OK = 1;
class Connexion { /* ... */ }
function connecte() { /* ... */ }
}
namespace { // código global
session_start();
$a = MonProjet\connecte();
echo MonProjet\Connexion::start();
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.basics">
<title>Uso de espacios de nombres: introducción</title>
<titleabbrev>Introducción</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Antes de discutir el uso de espacios de nombres, es importante comprender
cómo PHP deduce qué espacio de nombres está utilizando su código. Puede hacerse
una analogía simple entre los espacios de nombres de PHP y un sistema de archivos.
Hay tres formas de acceder a un archivo en un sistema de archivos:
<orderedlist>
<listitem>
<simpara>
Un nombre de archivo relativo, como <literal>foo.txt</literal>. Esto se resuelve
en <literal>dossiercourant/foo.txt</literal> donde <literal>dossiercourant</literal> es el
directorio de trabajo. Si el directorio actual es <literal>/home/foo</literal>,
este nombre se resuelve en <literal>/home/foo/foo.txt</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Una ruta relativa, como <literal>sub-dossier/foo.txt</literal>. Esto se
resuelve en <literal>dossiercourant/sub-dossier/foo.txt</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Una ruta absoluta, como <literal>/main/foo.txt</literal>. Esto se resuelve
en <literal>/main/foo.txt</literal>.
</simpara>
</listitem>
</orderedlist>
El mismo principio puede aplicarse a los espacios de nombres de PHP.
Por ejemplo, puede hacer referencia a una clase de tres maneras:
<orderedlist>
<listitem>
<simpara>
Un nombre sin calificador, o una clase sin prefijo, como
<literal>$a = new foo();</literal> o
<literal>foo::methodestatique();</literal>. Si el espacio de nombres actual
es <literal>espacedenomscourant</literal>, esto se resuelve en
<literal>espacedenomscourant\foo</literal>. Si el espacio de nombres es
global, es decir, el espacio de nombres sin nombre, esto se convierte en <literal>foo</literal>.
</simpara>
<simpara>
Una advertencia: los nombres sin calificador para funciones y constantes
se tomarán del espacio de nombres global, si la función
no está definida en el espacio de nombres actual. Ver
<link linkend="language.namespaces.fallback">Uso de espacios de nombres:
retorno al espacio de nombres global para funciones y constantes</link> para
más detalles.
</simpara>
</listitem>
<listitem>
<simpara>
Un nombre calificado, o una clase con prefijo como
<literal>$a = new sousespacedenoms\foo();</literal> o
<literal>sousespacedenoms\foo::methodestatique();</literal>. Si el espacio de nombres actual
es <literal>espacedenomscourant</literal>, esto se convierte
en <literal>espacedenomscourant\sousespacedenoms\foo</literal>. Si
el código es global, es decir, el espacio de nombres sin nombre,
esto se convierte en <literal>sousespacedenoms\foo</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Un nombre absoluto, o un nombre con prefijo con un operador global como
<literal>$a = new \espacedenomscourant\foo();</literal> o
<literal>\espacedenomscourant\foo::methodestatique();</literal>. Esto siempre
hace referencia al nombre literal especificado en el código: <literal>espacedenomscourant\foo</literal>.
</simpara>
</listitem>
</orderedlist>
</para>
<para>
Aquí hay un ejemplo de las tres sintaxis, en código real:
<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() {}
}
/* nombre no calificado */
foo(); // Se convierte en Foo\Bar\foo
foo::methodestatique(); // Se convierte en Foo\Bar\foo, método methodestatique
echo FOO; // Se convierte en la constante Foo\Bar\FOO
/* nombre calificado */
sousespacedenoms\foo(); // Se convierte en la función Foo\Bar\sousespacedenoms\foo
sousespacedenoms\foo::methodestatique(); // se convierte en la clase Foo\Bar\sousespacedenoms\foo,
// método methodestatique
echo sousespacedenoms\FOO; // Se convierte en la constante Foo\Bar\sousespacedenoms\FOO
/* nombre absoluto */
\Foo\Bar\foo(); // Se convierte en la función Foo\Bar\foo
\Foo\Bar\foo::methodestatique(); // Se convierte en la clase Foo\Bar\foo, método methodestatique
echo \Foo\Bar\FOO; // Se convierte en la constante Foo\Bar\FOO
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
Tenga en cuenta que para acceder a cualquier clase, función o constante
global, puede utilizarse un nombre absoluto, como
<function>\strlen</function> o <classname>\Exception</classname> o
\<constant>INI_ALL</constant>.
<example>
<title>Acceso a clases, funciones y constantes globales desde un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
$a = \strlen('hi'); // llama a la función global strlen
$b = \INI_ALL; // acceso a una constante INI_ALL
$c = new \Exception('error'); // instancia la clase global Exception
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.dynamic">
<title>Espacios de nombres y lenguaje dinámico</title>
<titleabbrev>Espacios de nombres y lenguaje dinámico</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
La implementación de espacios de nombres de PHP está influenciada por su naturaleza
dinámica como lenguaje de programación. Por lo tanto, para convertir código como el
del siguiente ejemplo en un espacio de nombres:
<example>
<title>Acceso dinámico a elementos</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; // muestra classname::__construct
$b = 'funcname';
$b(); // muestra funcname
echo constant('constname'), "\n"; // muestra global
?>
]]>
</programlisting>
</example>
Es necesario utilizar un nombre absoluto (el nombre de la clase, con su prefijo de espacio de nombres).
Tenga en cuenta que no hay diferencia entre un nombre absoluto y un nombre calificado
en un nombre de clase, función o constante dinámica, lo que hace que el backslash
inicial no sea necesario.
<example>
<title>Acceso dinámico a espacios de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace nomdelespacedenoms;
class classname
{
function __construct()
{
echo __METHOD__,"\n";
}
}
function funcname()
{
echo __FUNCTION__,"\n";
}
const constname = "namespaced";
/* Tenga en cuenta que si utiliza comillas dobles, "\\nomdelespacedenoms\\classname" debe usarse */
$a = '\nomdelespacedenoms\classname';
$obj = new $a; // muestra nomdelespacedenoms\classname::__construct
$a = 'nomdelespacedenoms\classname';
$obj = new $a; // también muestra nomdelespacedenoms\classname::__construct
$b = 'nomdelespacedenoms\funcname';
$b(); // muestra nomdelespacedenoms\funcname
$b = '\nomdelespacedenoms\funcname';
$b(); // también muestra nomdelespacedenoms\funcname
echo constant('\nomdelespacedenoms\constname'), "\n"; // muestra namespaced
echo constant('nomdelespacedenoms\constname'), "\n"; // también muestra namespaced
?>
]]>
</programlisting>
</example>
</para>
<para>
Se recomienda leer la <link linkend="language.namespaces.faq.quote">nota sobre la protección de espacios de nombres en cadenas</link>.
</para>
</sect1>
<sect1 xml:id="language.namespaces.nsconstants">
<title>El comando namespace y la constante __NAMESPACE__</title>
<titleabbrev>Comando namespace y __NAMESPACE__</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
PHP admite dos medios para acceder de manera abstracta a los elementos
en el espacio de nombres actual, a saber, la constante mágica
<constant>__NAMESPACE__</constant> y el comando <literal>namespace</literal>.
</para>
<para>
El valor de <constant>__NAMESPACE__</constant> es una cadena que contiene el nombre
del espacio de nombres actual. En el espacio global, sin nombre, contiene
una cadena vacía.
<example>
<title>Ejemplo con __NAMESPACE__, en un código con espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet;
echo '"', __NAMESPACE__, '"'; // muestra "MonProjet"
?>
]]>
</programlisting>
</example>
<example>
<title>Ejemplo con __NAMESPACE__, en un código con espacio de nombres global</title>
<programlisting role="php">
<![CDATA[
<?php
echo '"', __NAMESPACE__, '"'; // muestra ""
?>
]]>
</programlisting>
</example>
La constante <constant>__NAMESPACE__</constant> es útil para construir
dinámicamente nombres, como:
<example>
<title>Uso de __NAMESPACE__ para una construcción dinámica de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet;
function get($classname)
{
$a = __NAMESPACE__ . '\\' . $classname;
return new $a;
}
?>
]]>
</programlisting>
</example>
</para>
<para>
El comando <literal>namespace</literal> también puede usarse para
solicitar explícitamente un elemento del espacio de nombres actual, o de un
subespacio. Es el equivalente para los espacios de nombres del operador
<literal>self</literal> de las clases.
<example>
<title>El operador namespace, en un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace MonProjet;
use blah\blah as mine; // Ver "Uso de espacios de nombres: alias e importación"
blah\mine(); // llama a la función MonProjet\blah\mine()
namespace\blah\mine(); // llama a la función MonProjet\blah\mine()
namespace\func(); // llama a la función MonProjet\func()
namespace\sub\func(); // llama a la función MonProjet\sub\func()
namespace\cname::method(); // llama al método estático "method" de la clase MonProjet\cname
$a = new namespace\sub\cname(); // instancia un objeto de la clase MonProjet\sub\cname
$b = namespace\CONSTANT; // asigna el valor de la constante MonProjet\CONSTANT a $b
?>
]]>
</programlisting>
</example>
<example>
<title>El operador namespace, en el espacio de nombres global</title>
<programlisting role="php">
<![CDATA[
<?php
namespace\func(); // llama a la función func()
namespace\sub\func(); // llama a la función sub\func()
namespace\cname::method(); // llama al método estático "method" de la clase cname
$a = new namespace\sub\cname(); // instancia un objeto de la clase sub\cname
$b = namespace\CONSTANT; // asigna el valor de la constante CONSTANT a $b
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.importing">
<?phpdoc print-version-for="namespaces"?>
<title>Uso de espacios de nombres: importación y alias</title>
<titleabbrev>Importación y alias</titleabbrev>
<para>
La capacidad de hacer referencia a un nombre absoluto con un alias o importando
un espacio de nombres es estratégica. Es un beneficio similar a los enlaces
simbólicos en un sistema de archivos.
</para>
<para>
PHP puede crear alias(/importar) constantes, funciones, clases, interfaces,
traits, enumeraciones y espacios de nombres.
</para>
<para>
Un alias se crea con el operador <literal>use</literal>.
Aquí hay un ejemplo que presenta los cinco tipos de importación:
<example>
<title>Importación y alias con el operador use</title>
<programlisting role="php">
<![CDATA[
<?php
namespace foo;
use My\Full\Classname as Another;
// Esto es lo mismo que use My\Full\NSname as NSname
use My\Full\NSname;
// importación de una clase global
use ArrayObject;
// importación de una función
use function My\Full\functionName;
// alias de una función
use function My\Full\functionName as func;
// importación de una constante
use const My\Full\CONSTANT;
$obj = new namespace\Another; // instancia un objeto de la clase foo\Another
$obj = new Another; // instancia un objeto de la clase My\Full\Classname
NSname\subns\func(); // llama a la función My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // instancia un objeto de la clase ArrayObject
// Sin la instrucción "use ArrayObject" habríamos instanciado un objeto de la clase foo\ArrayObject
func(); // Llama a la función My\Full\functionName
echo CONSTANT; // muestra el valor de My\Full\CONSTANT
?>
]]>
</programlisting>
</example>
Tenga en cuenta que para los nombres con ruta (los nombres absolutos que contienen
separadores de espacios, como <literal>Foo\Bar</literal>, en comparación con
los nombres globales, como <literal>FooBar</literal>, que no los contienen),
el backslash inicial no es necesario y no se recomienda, ya que los nombres importados
deben ser absolutos y no se resuelven relativamente al espacio de nombres actual.
</para>
<para>
Además, PHP admite atajos prácticos, como las instrucciones use múltiples.
<example>
<title>Importación y alias múltiples con el operador use</title>
<programlisting role="php">
<![CDATA[
<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // instancia un objeto de la clase My\Full\Classname
NSname\subns\func(); // llama a la función My\Full\NSname\subns\func
?>
]]>
</programlisting>
</example>
</para>
<para>
La importación se realiza durante la compilación, por lo que no afecta
a las clases, funciones y constantes dinámicas.
<example>
<title>Importación y nombres de espacios dinámicos</title>
<programlisting role="php">
<![CDATA[
<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // instancia un objeto de la clase My\Full\Classname
$a = 'Another';
$obj = new $a; // instancia un objeto de la clase Another
?>
]]>
</programlisting>
</example>
</para>
<para>
Además, la importación solo afecta a los nombres sin calificación. Los nombres
absolutos siguen siendo absolutos y no se modifican por una importación.
<example>
<title>Importación y nombres de espacios absolutos</title>
<programlisting role="php">
<![CDATA[
<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // instancia un objeto de la clase My\Full\Classname
$obj = new \Another; // instancia un objeto de la clase Another
$obj = new Another\untruc; // instancia un objeto de la clase My\Full\Classname\untruc
$obj = new \Another\untruc; // instancia un objeto de la clase Another\untruc
?>
]]>
</programlisting>
</example>
</para>
<sect2 xml:id="language.namespaces.importing.scope">
<title>Reglas de contexto para la importación</title>
<para>
La palabra clave <literal>use</literal> debe declararse en el contexto más
externo de un archivo (el contexto global) o en las declaraciones de espacio
de nombres. Esto se debe a que la importación se realiza durante la compilación
y no durante la ejecución, por lo que no se pueden apilar los contextos. El ejemplo
siguiente muestra usos incorrectos de la palabra clave <literal>use</literal>:
</para>
<para>
<example>
<title>Reglas de importación incorrectas</title>
<programlisting role="php">
<![CDATA[
<?php
namespace Languages;
function toGreenlandic
{
use Languages\Danish;
// ...
}
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
Las reglas de importación se basan en archivos, lo que significa que los archivos
incluidos no heredarán <emphasis>PAS</emphasis> las reglas de importación del archivo padre.
</para>
</note>
</sect2>
<sect2 xml:id="language.namespaces.importing.group">
<title>Declaración del grupo <literal>use</literal></title>
<para>
Las clases, funciones y constantes importadas desde
el mismo &namespace; pueden agruparse en una
sola instrucción &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;
// es equivalente a la siguiente declaración de grupo use
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>Espacio de nombres global</title>
<titleabbrev>Global</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
Sin ninguna definición de espacio de nombres, todas las clases y las funciones
se colocan en el espacio de nombres global: como en PHP antes de que los espacios
de nombres fueran introducidos. Al prefijar un nombre con un backslash
<literal>\</literal>, se puede solicitar el uso del espacio de nombres
global, incluso en un contexto de espacio de nombres específico.
<example>
<title>Especificación de espacio de nombres global</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A\B\C;
/* Esta función es A\B\C\fopen */
function fopen() {
/* ... */
$f = \fopen(...); // llamada a fopen global
return $f;
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.fallback">
<title>Uso de espacios de nombres: retorno al espacio global para funciones y constantes</title>
<titleabbrev>Retorno al espacio global</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
En un espacio de nombres, cuando PHP encuentra un nombre sin calificación,
ya sea una clase, una función o una constante, lo resuelve con diferentes
prioridades. Los nombres de clases siempre se resuelven con el espacio de nombres actual.
Para acceder a clases internas o a clases que no están en
un espacio de nombres, es necesario representarlas con su nombre absoluto, como:
<example>
<title>Acceso a clases globales desde un espacio de nombres</title>
<programlisting role="php">
<![CDATA[
<?php
namespace A\B\C;
class Exception extends \Exception {}
$a = new Exception('hi'); // $a es un objeto de la clase A\B\C\Exception
$b = new \Exception('hi'); // $b es un objeto de la clase Exception
$c = new ArrayObject; // error fatal, clase A\B\C\ArrayObject no encontrada
?>
]]>
</programlisting>
</example>
</para>
<para>
Para las funciones y constantes, PHP las buscará en el espacio
global si no puede encontrarlas en el espacio de nombres actual.
<example>
<title>Acceso a funciones y constantes globales en un espacio de nombres</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"; // muestra "45"
echo INI_ALL, "\n"; // muestra "7": acceso al espacio de nombres global INI_ALL
echo strlen('hi'), "\n"; // muestra "1"
if (is_array('hi')) { // muestra "no es un array"
echo "es un array\n";
} else {
echo "no es un array\n";
}
?>
]]>
</programlisting>
</example>
</para>
</sect1>
<sect1 xml:id="language.namespaces.rules">
<title>Reglas de resolución de nombres</title>
<titleabbrev>Reglas de resolución de nombres</titleabbrev>
<?phpdoc print-version-for="namespaces"?>
<para>
En el contexto de las reglas de resolución, hay varias definiciones importantes:
<variablelist>
<title>Definiciones para espacios de nombres</title>
<varlistentry>
<term>nombre no calificado</term>
<listitem>
<para>
Esto es un identificador que no contiene un separador de espacio de nombres.
Por ejemplo: <literal>Foo</literal>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>nombre calificado</term>
<listitem>
<para>
Esto es un identificador que contiene un separador de espacio de nombres.
Por ejemplo: <literal>Foo\Bar</literal>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Nombre absoluto</term>
<listitem>
<para>
Esto es un identificador que comienza con un separador de espacio de nombres.
Por ejemplo: <literal>\Foo\Bar</literal>. El espacio de nombres <literal>Foo</literal>
también es un nombre absoluto.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Nombre Relativo</term>
<listitem>
<para>
Es un identificador que comienza con <literal>namespace</literal>, como
<literal>namespace\Foo\Bar</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Los nombres se resuelven siguiendo las siguientes reglas:
<orderedlist>
<listitem>
<simpara>
Los nombres absolutos siempre se traducen a nombres sin el separador de namespace.
Por ejemplo, <literal>\A\B</literal> se traduce a <literal>A\B</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Todos los nombres que no son absolutos se traducen con
<literal>namespace</literal> reemplazado por el namespace actual.
Si el nombre aparece en el namespace global, el prefijo
<literal>namespace\</literal> se elimina. Por ejemplo <literal>namespace\A</literal>
en el namespace <literal>X\Y</literal> se traduce a <literal>X\Y\A</literal>.
El mismo nombre en el namespace global se traduce a <literal>A</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Para los nombres absolutos, el primer segmento se traduce
de acuerdo con la clase/namespace de la tabla de importación.
Por ejemplo, si el namespace <literal>A\B\C</literal> se importa como <literal>C</literal>, el nombre <literal>C\D\E</literal> se traduce a <literal>A\B\C\D\E</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Para los nombres absolutos, si ninguna regla de importación
se aplica, el namespace actual se prefiere al nombre.
Por ejemplo, el nombre <literal>C\D\E</literal> en el namespace <literal>A\B</literal>,
se traduce a <literal>A\B\C\D\E</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Para los nombres absolutos, el nombre se traduce en relación con la tabla actual de importación para el tipo de símbolo respectivo.
Esto significa que un nombre que se asemeja a una clase se traduce de acuerdo con la tabla de importación de
class/namespace, los nombres de funciones utilizando la
tabla de importación de funciones, y las constantes utilizando la tabla de importación de constantes.
Por ejemplo, después
<literal>use A\B\C;</literal> un uso como <literal>new C()</literal> corresponde al nombre
<literal>A\B\C()</literal>. De manera similar, después de <literal>use function A\B\foo;</literal> un uso
como <literal>foo()</literal> corresponde al nombre <literal>A\B\foo</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Para los nombres relativos, si ninguna regla se aplica, y el nombre
hace referencia a una clase, el namespace actual sirve como prefijo.
Por ejemplo <literal>new C()</literal> en el namespace
<literal>A\B</literal> corresponde al nombre <literal>A\B\C</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Para los nombres relativos, si ninguna regla se aplica, y el nombre
hace referencia a una función o constante, y el código está
fuera del namespace global, el nombre se resuelve durante la ejecución.
Supongamos que el código está en el namespace
<literal>A\B</literal>, aquí es cómo se resuelve una llamada a la función <literal>foo()</literal>:
</simpara>
<orderedlist>