1
0
mirror of https://github.com/php/doc-es.git synced 2026-03-23 23:12:09 +01:00
Files
archived-doc-es/language/types/array.xml
2025-07-27 14:38:45 +02:00

1555 lines
40 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: e8600fec147c06a6f4dcfb02f0f0e95b2f89d1e3 Maintainer: PhilDaiguille Status: ready -->
<!-- Reviewed: no -->
<sect1 xml:id="language.types.array">
<title>Arrays</title>
<para>
Un <type>array</type> en PHP es en realidad un mapa ordenado. Un mapa es un tipo que
asocia <emphasis>valores</emphasis> a <emphasis>claves</emphasis>. Este tipo
está optimizado para varios usos diferentes; puede ser tratado como un array,
lista (vector), tabla hash (una implementación de un mapa), diccionario,
colección, pila, cola, y probablemente más. Como los valores <type>array</type> pueden
ser otros <type>array</type>s, árboles y arrays <type>array</type>s
multidimensionales también son posibles.
</para>
<para>
La explicación de esas estructuras de datos está fuera del alcance de este manual, pero
al menos se proporciona un ejemplo para cada una de ellas. Para más información, consulte
la considerable literatura que existe sobre este amplio tema.
</para>
<sect2 xml:id="language.types.array.syntax">
<title>Sintaxis</title>
<sect3 xml:id="language.types.array.syntax.array-func">
<title>Especificación con <function>array</function></title>
<para>
Un <type>array</type> puede ser creado usando la construcción de lenguaje <function>array</function>. Toma cualquier número de pares
<literal><replaceable>clave</replaceable> =&gt; <replaceable>valor</replaceable></literal> separados por comas
como argumentos.
</para>
<synopsis>
array(
<optional><replaceable>clave</replaceable> =&gt; </optional><replaceable>valor</replaceable>,
<optional><replaceable>clave2</replaceable> =&gt; </optional><replaceable>valor2</replaceable>,
<optional><replaceable>clave3</replaceable> =&gt; </optional><replaceable>valor3</replaceable>,
...
)</synopsis>
<!-- Do not fix the whitespace for the synopsis end element. A limitation of PhD prevents proper trimming -->
<para>
La coma después del último elemento del array es opcional y puede ser omitida. Esto se hace usualmente
para arrays de una sola línea, es decir, <literal>array(1, 2)</literal> es preferido sobre
<literal>array(1, 2, )</literal>. Para arrays de múltiples líneas, por otro lado, la coma final
es comúnmente usada, ya que permite una adición más fácil de nuevos elementos al final.
</para>
<note>
<para>
Existe una sintaxis corta para arrays que reemplaza
<literal>array()</literal> con <literal>[]</literal>.
</para>
</note>
<example>
<title>Un array simple</title>
<programlisting role="php">
<![CDATA[
<?php
$array1 = array(
"foo" => "bar",
"bar" => "foo",
);
// Usando la sintaxis corta de array
$array2 = [
"foo" => "bar",
"bar" => "foo",
];
var_dump($array1, $array2);
?>
]]>
</programlisting>
</example>
<para>
La <replaceable>clave</replaceable> puede ser un <type>int</type>
o un <type>string</type>. El <replaceable>valor</replaceable> puede ser
de cualquier tipo.
</para>
<para xml:id="language.types.array.key-casts">
Además, las siguientes conversiones de <replaceable>clave</replaceable> ocurrirán:
<itemizedlist>
<listitem>
<simpara>
<type>String</type>s que contienen <type>int</type>s decimales válidos, a menos que el número esté precedido por un signo <literal>+</literal>, serán convertidos al
tipo <type>int</type>. Por ejemplo, la clave <literal>"8"</literal> será almacenada bajo <literal>8</literal>. Por otro lado, <literal>"08"</literal> no
será convertido, ya que no es un entero decimal válido.
</simpara>
</listitem>
<listitem>
<simpara>
Los <type>float</type>s también son convertidos a <type>int</type>s, lo que significa que la
parte fraccional será truncada. Por ejemplo, la clave <literal>8.7</literal> será almacenada bajo <literal>8</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Los <type>bool</type>s son convertidos a <type>int</type>s también, es decir, la clave
&true; será almacenada bajo <literal>1</literal>
y la clave &false; bajo <literal>0</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
<type>Null</type> será convertido a una cadena vacía, es decir, la clave
<literal>null</literal> será almacenada bajo <literal>""</literal>.
</simpara>
</listitem>
<listitem>
<simpara>
Los <type>array</type>s y <type>object</type>s <emphasis>no pueden</emphasis> ser usados como claves.
Hacerlo resultará en una advertencia: <literal>Illegal offset type</literal>.
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
Si múltiples elementos en la declaración del array usan la misma clave, solo el último será
usado ya que todos los demás son sobrescritos.
</para>
<example>
<title>Ejemplo de conversión de tipos y sobrescritura</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
1 => "a",
"1" => "b",
1.5 => "c",
true => "d",
);
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(1) {
[1]=>
string(1) "d"
}
]]>
</screen>
<para>
Como todas las claves en el ejemplo anterior son convertidas a <literal>1</literal>, el valor será sobrescrito
en cada nuevo elemento y el último valor asignado <literal>"d"</literal> es el único que queda.
</para>
</example>
<para>
Los arrays de PHP pueden contener claves <type>int</type> y <type>string</type> al mismo tiempo
ya que PHP no distingue entre arrays indexados y asociativos.
</para>
<example>
<title>Claves <type>int</type> y <type>string</type> mezcladas</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
100 => -100,
-100 => 100,
);
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(4) {
["foo"]=>
string(3) "bar"
["bar"]=>
string(3) "foo"
[100]=>
int(-100)
[-100]=>
int(100)
}
]]>
</screen>
</example>
<para>
La <replaceable>clave</replaceable> es opcional. Si no se especifica, PHP usará
el incremento de la clave <type>int</type> más grande usada previamente.
</para>
<example>
<title>Arrays indexados sin clave</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array("foo", "bar", "hello", "world");
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(4) {
[0]=>
string(3) "foo"
[1]=>
string(3) "bar"
[2]=>
string(5) "hello"
[3]=>
string(5) "world"
}
]]>
</screen>
</example>
<para>
Es posible especificar la clave solo para algunos elementos y omitirla para otros:
</para>
<example>
<title>Claves no en todos los elementos</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
"a",
"b",
6 => "c",
"d",
);
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(4) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[6]=>
string(1) "c"
[7]=>
string(1) "d"
}
]]>
</screen>
<para>
Como puede ver, el último valor <literal>"d"</literal> fue asignado con la clave
<literal>7</literal>. Esto es porque la clave entera más grande antes de eso
era <literal>6</literal>.
</para>
</example>
<example>
<title>Ejemplo complejo de conversión de tipos y sobrescritura</title>
<para>
Este ejemplo incluye todas las variaciones de conversión de tipos de claves y sobrescritura
de elementos.
</para>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
1 => 'a',
'1' => 'b', // el valor "a" será sobrescrito por "b"
1.5 => 'c', // el valor "b" será sobrescrito por "c"
-1 => 'd',
'01' => 'e', // como esto no es una cadena entera, NO sobrescribirá la clave para 1
'1.5' => 'f', // como esto no es una cadena entera, NO sobrescribirá la clave para 1
true => 'g', // el valor "c" será sobrescrito por "g"
false => 'h',
'' => 'i',
null => 'j', // el valor "i" será sobrescrito por "j"
'k', // el valor "k" es asignado con la clave 2. Esto es porque la clave entera más grande antes de eso era 1
2 => 'l', // el valor "k" será sobrescrito por "l"
);
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(7) {
[1]=>
string(1) "g"
[-1]=>
string(1) "d"
["01"]=>
string(1) "e"
["1.5"]=>
string(1) "f"
[0]=>
string(1) "h"
[""]=>
string(1) "j"
[2]=>
string(1) "l"
}
]]>
</screen>
</example>
<example>
<title>Ejemplo de índice negativo</title>
<simpara>
Al asignar una clave entera negativa <literal>n</literal>, PHP se asegurará de
asignar la siguiente clave a <literal>n+1</literal>.
</simpara>
<programlisting role="php">
<![CDATA[
<?php
$array = [];
$array[-5] = 1;
$array[] = 2;
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(2) {
[-5]=>
int(1)
[-4]=>
int(2)
}
]]>
</screen>
<warning>
<simpara>
Antes de PHP 8.3.0, asignar una clave entera negativa <literal>n</literal> asignaría
la siguiente clave a <literal>0</literal>, el ejemplo anterior produciría
por lo tanto:
</simpara>
<informalexample>
<screen>
<![CDATA[
array(2) {
[-5]=>
int(1)
[0]=>
int(2)
}
]]>
</screen>
</informalexample>
</warning>
</example>
</sect3>
<sect3 xml:id="language.types.array.syntax.accessing">
<title>Accediendo a elementos de array con sintaxis de corchetes</title>
<para>
Los elementos de array pueden ser accedidos usando la sintaxis <literal>array[clave]</literal>.
</para>
<example>
<title>Accediendo a elementos de array</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
"foo" => "bar",
42 => 24,
"multi" => array(
"dimensional" => array(
"array" => "foo"
)
)
);
var_dump($array["foo"]);
var_dump($array[42]);
var_dump($array["multi"]["dimensional"]["array"]);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
string(3) "bar"
int(24)
string(3) "foo"
]]>
</screen>
</example>
<note>
<para>
Antes de PHP 8.0.0, los corchetes y las llaves podían ser usados indistintamente
para acceder a elementos de array (por ejemplo, <literal>$array[42]</literal> y <literal>$array{42}</literal>
harían lo mismo en el ejemplo anterior).
La sintaxis de llaves fue deprecada a partir de PHP 7.4.0 y ya no es soportada a partir de PHP 8.0.0.
</para>
</note>
<example>
<title>Desreferenciación de array</title>
<programlisting role="php">
<![CDATA[
<?php
function getArray() {
return array(1, 2, 3);
}
$secondElement = getArray()[1];
var_dump($secondElement);
?>
]]>
</programlisting>
</example>
<note>
<para>
Intentar acceder a una clave de array que no ha sido definida es
lo mismo que acceder a cualquier otra variable no definida:
se emitirá un mensaje de error de nivel <constant>E_WARNING</constant>
(nivel <constant>E_NOTICE</constant> antes de PHP 8.0.0) y el resultado será &null;.
</para>
</note>
<note>
<para>
La desreferenciación de array de un valor escalar que no es un <type>string</type>
produce &null;. Antes de PHP 7.4.0, esto no emitía un mensaje de error.
A partir de PHP 7.4.0, esto emite <constant>E_NOTICE</constant>;
a partir de PHP 8.0.0, esto emite <constant>E_WARNING</constant>.
</para>
</note>
</sect3>
<sect3 xml:id="language.types.array.syntax.modifying">
<title>Creando/modificando con sintaxis de corchetes</title>
<para>
Un <type>array</type> existente puede ser modificado asignando explícitamente valores
en él.
</para>
<para>
Esto se hace asignando valores al <type>array</type>, especificando
la clave entre corchetes. La clave también puede ser omitida, resultando en un par vacío de
corchetes (<literal>[]</literal>).
</para>
<synopsis>
$arr[<replaceable>clave</replaceable>] = <replaceable>valor</replaceable>;
$arr[] = <replaceable>valor</replaceable>;
// <replaceable>clave</replaceable> puede ser un <type>int</type> o <type>string</type>
// <replaceable>valor</replaceable> puede ser cualquier valor de cualquier tipo</synopsis>
<para>
Si <varname>$arr</varname> no existe aún o está establecido a &null; o &false;, será creado, por lo que esto es
también una forma alternativa de crear un <type>array</type>. Sin embargo, esta práctica es
desaconsejada porque si <varname>$arr</varname> ya contiene
algún valor (por ejemplo, <type>string</type> de una variable de solicitud) entonces este
valor permanecerá en su lugar y <literal>[]</literal> puede en realidad representar
el <link linkend="language.types.string.substr">operador de acceso a string</link>. Siempre es mejor inicializar una variable mediante una asignación directa.
</para>
<note>
<simpara>
A partir de PHP 7.1.0, aplicar el operador de índice vacío en un string lanza un error fatal.
Anteriormente, el string era convertido silenciosamente a un array.
</simpara>
</note>
<note>
<simpara>
A partir de PHP 8.1.0, crear un nuevo array a partir de un valor &false; está deprecado.
Crear un nuevo array a partir de valores &null; y no definidos sigue estando permitido.
</simpara>
</note>
<para>
Para cambiar un cierto
valor, asigne un nuevo valor a ese elemento usando su clave. Para eliminar un
par clave/valor, llame a la función <function>unset</function> sobre él.
</para>
<example>
<title>Usando corchetes con arrays</title>
<programlisting role="php">
<![CDATA[
<?php
$arr = array(5 => 1, 12 => 2);
$arr[] = 56; // Esto es lo mismo que $arr[13] = 56;
// en este punto del script
$arr["x"] = 42; // Esto añade un nuevo elemento al
// array con clave "x"
unset($arr[5]); // Esto elimina el elemento del array
var_dump($arr);
unset($arr); // Esto elimina todo el array
var_dump($arr);
?>
]]>
</programlisting>
</example>
<note>
<para>
Como se mencionó anteriormente, si no se especifica una clave, se toma el máximo de los índices
<type>int</type> existentes, y la nueva clave será ese valor máximo más 1 (pero al menos 0). Si no existen índices
<type>int</type> aún, la clave será <literal>0</literal> (cero).
</para>
<para>
Tenga en cuenta que el índice entero máximo usado para esto <emphasis>no necesita
existir actualmente en el <type>array</type></emphasis>. Solo necesita haber
existido en el <type>array</type> en algún momento desde la última vez que el
<type>array</type> fue reindexado. El siguiente ejemplo lo ilustra:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
// Crear un array simple.
$array = array(1, 2, 3, 4, 5);
print_r($array);
// Ahora eliminar cada elemento, pero dejar el array en sí intacto:
foreach ($array as $i => $value) {
unset($array[$i]);
}
print_r($array);
// Añadir un elemento (note que la nueva clave es 5, en lugar de 0).
$array[] = 6;
print_r($array);
// Reindexar:
$array = array_values($array);
$array[] = 7;
print_r($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
Array
(
)
Array
(
[5] => 6
)
Array
(
[0] => 6
[1] => 7
)
]]>
</screen>
</informalexample>
</note>
</sect3>
<sect3 xml:id="language.types.array.syntax.destructuring">
<title>Desestructuración de arrays</title>
<para>
Los arrays pueden ser desestructurados usando la construcción de lenguaje <literal>[]</literal> (a partir de PHP 7.1.0) o
<function>list</function>. Estas
construcciones pueden ser usadas para desestructurar un array en variables distintas.
</para>
<example>
<title>Desestructuración de arrays</title>
<programlisting role="php">
<![CDATA[
<?php
$source_array = ['foo', 'bar', 'baz'];
[$foo, $bar, $baz] = $source_array;
echo $foo, PHP_EOL; // imprime "foo"
echo $bar, PHP_EOL; // imprime "bar"
echo $baz, PHP_EOL; // imprime "baz"
?>
]]>
</programlisting>
</example>
<para>
La desestructuración de arrays puede ser usada en &foreach; para desestructurar
un array multidimensional mientras se itera sobre él.
</para>
<example>
<title>Desestructuración de arrays en foreach</title>
<programlisting role="php">
<![CDATA[
<?php
$source_array = [
[1, 'John'],
[2, 'Jane'],
];
foreach ($source_array as [$id, $name]) {
echo "{$id}: '{$name}'\n";
}
?>
]]>
</programlisting>
</example>
<para>
Los elementos del array serán ignorados si la variable no es proporcionada. La desestructuración de arrays
siempre comienza en el índice <literal>0</literal>.
</para>
<example>
<title>Ignorando elementos</title>
<programlisting role="php">
<![CDATA[
<?php
$source_array = ['foo', 'bar', 'baz'];
// Asignar el elemento en el índice 2 a la variable $baz
[, , $baz] = $source_array;
echo $baz; // imprime "baz"
?>
]]>
</programlisting>
</example>
<para>
A partir de PHP 7.1.0, los arrays asociativos también pueden ser desestructurados. Esto también
permite una selección más fácil del elemento correcto en arrays indexados numéricamente ya que el índice puede ser especificado explícitamente.
</para>
<example>
<title>Desestructuración de arrays asociativos</title>
<programlisting role="php">
<![CDATA[
<?php
$source_array = ['foo' => 1, 'bar' => 2, 'baz' => 3];
// Asignar el elemento en el índice 'baz' a la variable $three
['baz' => $three] = $source_array;
echo $three, PHP_EOL; // imprime 3
$source_array = ['foo', 'bar', 'baz'];
// Asignar el elemento en el índice 2 a la variable $baz
[2 => $baz] = $source_array;
echo $baz, PHP_EOL; // imprime "baz"
?>
]]>
</programlisting>
</example>
<para>
La desestructuración de arrays puede ser usada para un intercambio fácil de dos variables.
</para>
<example>
<title>Intercambiando dos variables</title>
<programlisting role="php">
<![CDATA[
<?php
$a = 1;
$b = 2;
[$b, $a] = [$a, $b];
echo $a, PHP_EOL; // imprime 2
echo $b, PHP_EOL; // imprime 1
?>
]]>
</programlisting>
</example>
<note>
<para>
El operador de propagación (<literal>...</literal>) no es soportado en asignaciones.
</para>
</note>
<note>
<para>
Intentar acceder a una clave de array que no ha sido definida es
lo mismo que acceder a cualquier otra variable no definida:
se emitirá un mensaje de error de nivel <constant>E_WARNING</constant>
(nivel <constant>E_NOTICE</constant> antes de PHP 8.0.0) y el resultado será &null;.
</para>
</note>
</sect3>
</sect2><!-- end syntax -->
<sect2 xml:id="language.types.array.useful-funcs">
<title>Funciones útiles</title>
<para>
Hay bastantes funciones útiles para trabajar con arrays. Vea la
sección de <link linkend="ref.array">funciones de array</link>.
</para>
<note>
<para>
La función <function>unset</function> permite eliminar claves de un
<type>array</type>. Tenga en cuenta que el array <emphasis>no</emphasis> será
reindexado. Si se desea un comportamiento de "eliminar y desplazar", el
<type>array</type> puede ser reindexado usando la
función <function>array_values</function>.
</para>
<example>
<title>Eliminando elementos intermedios</title>
<programlisting role="php">
<![CDATA[
<?php
$a = array(1 => 'one', 2 => 'two', 3 => 'three');
/* producirá un array que habría sido definido como
$a = array(1 => 'one', 3 => 'three');
y NO
$a = array(1 => 'one', 2 =>'three');
*/
unset($a[2]);
var_dump($a);
$b = array_values($a);
// Ahora $b es array(0 => 'one', 1 =>'three')
var_dump($b);
?>
]]>
</programlisting>
</example>
</note>
<para>
La estructura de control &foreach;
existe específicamente para <type>array</type>s. Proporciona una forma fácil
de recorrer un <type>array</type>.
</para>
</sect2>
<sect2 xml:id="language.types.array.donts">
<title>Qué hacer y qué no hacer con arrays</title>
<sect3 xml:id="language.types.array.foo-bar">
<title>¿Por qué <literal>$foo[bar]</literal> está mal?</title>
<para>
Siempre use comillas alrededor de un índice de array literal de cadena. Por ejemplo,
<literal>$foo['bar']</literal> es correcto, mientras que
<literal>$foo[bar]</literal> no lo es. Pero, ¿por qué? Es común encontrar este
tipo de sintaxis en scripts antiguos:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$foo[bar] = 'enemy';
echo $foo[bar];
// etc
?>
]]>
</programlisting>
</informalexample>
<para>
Esto está mal, pero funciona. La razón es que este código tiene una constante no definida (<literal>bar</literal>)
en lugar de un <type>string</type> (<literal>'bar'</literal> - note las comillas). Funciona porque PHP
convierte automáticamente una <emphasis>cadena sin comillas</emphasis> (una cadena sin comillas que no
corresponde a ningún símbolo conocido) en un <type>string</type> que contiene la cadena sin comillas.
Por ejemplo, si no hay una constante definida llamada <constant>bar</constant>, entonces PHP
sustituirá la cadena <literal>'bar'</literal> y la usará.
</para>
<warning>
<simpara>
La opción de tratar una constante no definida como una cadena sin comillas emite un error
de nivel <constant>E_NOTICE</constant>.
Esto ha sido deprecado a partir de PHP 7.2.0, y emite un error
de nivel <constant>E_WARNING</constant>.
A partir de PHP 8.0.0, ha sido eliminado y lanza una
excepción <classname>Error</classname>.
</simpara>
</warning>
<simpara>
Esto no significa que <emphasis>siempre</emphasis> se deban poner comillas a la clave. No
ponga comillas a las claves que son <link linkend="language.constants">constantes</link> o
<link linkend="language.variables">variables</link>, ya que esto evitará
que PHP las interprete.
</simpara>
<example>
<title>Claves con comillas</title>
<programlisting role="php">
<![CDATA[
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('html_errors', false);
// Array simple:
$array = array(1, 2);
$count = count($array);
for ($i = 0; $i < $count; $i++) {
echo "\nRevisando $i: \n";
echo "Incorrecto: " . $array['$i'] . "\n";
echo "Correcto: " . $array[$i] . "\n";
echo "Incorrecto: {$array['$i']}\n";
echo "Correcto: {$array[$i]}\n";
}
?>
]]>
</programlisting>
</example>
&example.outputs;
<screen>
<![CDATA[
Revisando 0:
Notice: Índice no definido: $i en /ruta/al/script.html en la línea 9
Incorrecto:
Correcto: 1
Notice: Índice no definido: $i en /ruta/al/script.html en la línea 11
Incorrecto:
Correcto: 1
Revisando 1:
Notice: Índice no definido: $i en /ruta/al/script.html en la línea 9
Incorrecto:
Correcto: 2
Notice: Índice no definido: $i en /ruta/al/script.html en la línea 11
Incorrecto:
Correcto: 2
]]>
</screen>
<para>
Más ejemplos para demostrar este comportamiento:
</para>
<example>
<title>Más ejemplos</title>
<programlisting role="php">
<![CDATA[
<?php
// Mostrar todos los errores
error_reporting(E_ALL);
$arr = array('fruit' => 'apple', 'veggie' => 'carrot');
// Correcto
echo $arr['fruit'], PHP_EOL; // apple
echo $arr['veggie'], PHP_EOL; // carrot
// Incorrecto. Esto funciona pero también lanza un error de PHP debido a
// una constante no definida llamada fruit
//
// Error: Constante no definida "fruit"
try {
echo $arr[fruit]; // apple
} catch (Error $e) {
echo get_class($e), ': ', $e->getMessage(), PHP_EOL;
}
// Esto define una constante para demostrar lo que está pasando. El valor 'veggie'
// es asignado a una constante llamada fruit.
define('fruit', 'veggie');
// Note la diferencia ahora
echo $arr['fruit'], PHP_EOL; // apple
echo $arr[fruit], PHP_EOL; // carrot
// Lo siguiente está bien, ya que está dentro de una cadena. Las constantes no son buscadas
// dentro de cadenas, por lo que no ocurre E_NOTICE aquí
echo "Hello $arr[fruit]", PHP_EOL; // Hello apple
// Con una excepción: las llaves que rodean arrays dentro de cadenas permiten que las constantes
// sean interpretadas
echo "Hello {$arr[fruit]}", PHP_EOL; // Hello carrot
echo "Hello {$arr['fruit']}", PHP_EOL; // Hello apple
// La concatenación es otra opción
echo "Hello " . $arr['fruit'], PHP_EOL; // Hello apple
?>
]]>
</programlisting>
</example>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
// Esto no funcionará, y resultará en un error de análisis, como:
// Error de análisis: error de análisis, esperando T_STRING o T_VARIABLE o T_NUM_STRING'
// Esto, por supuesto, también se aplica al usar superglobals en cadenas
print "Hello $arr['fruit']";
print "Hello $_GET['foo']";
?>
]]>
</programlisting>
</informalexample>
<para>
Cuando <link linkend="ini.error-reporting">error_reporting</link> está configurado para
mostrar errores de nivel <constant>E_NOTICE</constant> (configurándolo a
<constant>E_ALL</constant>, por ejemplo), tales usos se harán inmediatamente
visibles. Por defecto,
<link linkend="ini.error-reporting">error_reporting</link> está configurado para no
mostrar notificaciones.
</para>
<para>
Como se establece en la sección de <link linkend="language.types.array.syntax">sintaxis</link>,
lo que está dentro de los corchetes ('<literal>[</literal>' y
'<literal>]</literal>') debe ser una expresión. Esto significa que el código como
este funciona:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
echo $arr[somefunc($bar)];
?>
]]>
</programlisting>
</informalexample>
<para>
Este es un ejemplo de usar el valor de retorno de una función como índice del array. PHP
también conoce las constantes:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$error_descriptions[E_ERROR] = "Ha ocurrido un error fatal";
$error_descriptions[E_WARNING] = "PHP emitió una advertencia";
$error_descriptions[E_NOTICE] = "Esto es solo una notificación informal";
?>
]]>
</programlisting>
</informalexample>
<para>
Note que <constant>E_ERROR</constant> también es un identificador válido, al igual que
<literal>bar</literal> en el primer ejemplo. Pero el último ejemplo es de hecho
lo mismo que escribir:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$error_descriptions[1] = "Ha ocurrido un error fatal";
$error_descriptions[2] = "PHP emitió una advertencia";
$error_descriptions[8] = "Esto es solo una notificación informal";
?>
]]>
</programlisting>
</informalexample>
<para>
porque <constant>E_ERROR</constant> es igual a <literal>1</literal>, etc.
</para>
<sect4 xml:id="language.types.array.foo-bar.why">
<title>Entonces, ¿por qué está mal?</title>
<para>
En algún momento en el futuro, el equipo de PHP podría querer añadir otra
constante o palabra clave, o una constante en otro código podría interferir. Por
ejemplo, ya está mal usar las palabras <literal>empty</literal> y
<literal>default</literal> de esta manera, ya que son
<link linkend="reserved">palabras clave reservadas</link>.
</para>
<note>
<simpara>
Para reiterar, dentro de una cadena entre comillas dobles, es válido
no rodear los índices de array con comillas, por lo que <literal>"$foo[bar]"</literal>
es válido. Vea los ejemplos anteriores para más detalles sobre por qué, así como la sección
sobre <link linkend="language.types.string.parsing">análisis de variables en
cadenas</link>.
</simpara>
</note>
</sect4>
</sect3>
</sect2>
<sect2 xml:id="language.types.array.casting">
<title>Conversión a array</title>
<para>
Para cualquiera de los tipos <type>int</type>, <type>float</type>,
<type>string</type>, <type>bool</type> y <type>resource</type>,
convertir un valor a un <type>array</type> resulta en un array con un solo
elemento con índice cero y el valor del escalar que fue convertido. En
otras palabras, <code>(array) $scalarValue</code> es exactamente lo mismo que
<literal>array($scalarValue)</literal>.
</para>
<para>
Si un <type>object</type> es convertido a un <type>array</type>, el resultado
es un <type>array</type> cuyos elementos son las propiedades del <type>object</type>.
Las claves son los nombres de las variables miembro, con algunas excepciones notables: las propiedades enteras son inaccesibles;
las variables privadas tienen el nombre de la clase antepuesto al nombre de la variable;
las variables protegidas tienen un '*' antepuesto al nombre de la variable. Estos
valores antepuestos tienen bytes <literal>NUL</literal> en ambos lados.
Las <link linkend="language.oop5.properties.typed-properties">propiedades tipadas</link>
no inicializadas son descartadas silenciosamente.
</para>
<example>
<title>Conversión a un array</title>
<programlisting role="php">
<![CDATA[
<?php
class A {
private $B;
protected $C;
public $D;
function __construct()
{
$this->{1} = null;
}
}
var_export((array) new A());
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array (
'' . "\0" . 'A' . "\0" . 'B' => NULL,
'' . "\0" . '*' . "\0" . 'C' => NULL,
'D' => NULL,
1 => NULL,
)
]]>
</screen>
</example>
<para>
Estos <literal>NUL</literal> pueden resultar en algún comportamiento inesperado:
</para>
<example>
<title>Conversión de un objeto a un array</title>
<programlisting role="php">
<![CDATA[
<?php
class A {
private $A; // Esto se convertirá en '\0A\0A'
}
class B extends A {
private $A; // Esto se convertirá en '\0B\0A'
public $AA; // Esto se convertirá en 'AA'
}
var_dump((array) new B());
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(3) {
["BA"]=>
NULL
["AA"]=>
NULL
["AA"]=>
NULL
}
]]>
</screen>
</example>
<para>
Lo anterior parecerá tener dos claves llamadas 'AA', aunque una de ellas está
realmente llamada '\0A\0A'.
</para>
<para>
Convertir &null; a un <type>array</type> resulta en un
<type>array</type> vacío.
</para>
</sect2>
<sect2 xml:id="language.types.array.comparing">
<title>Comparación</title>
<para>
Es posible comparar arrays con la función <function>array_diff</function>
y con los
<link linkend="language.operators.array">operadores de array</link>.
</para>
</sect2>
<sect2 xml:id="language.types.array.unpacking">
<title>Desempaquetado de arrays</title>
<para>
Un array precedido por <code>...</code> será expandido en su lugar durante la definición del array.
Solo arrays y objetos que implementan <interfacename>Traversable</interfacename> pueden ser expandidos.
El desempaquetado de arrays con <code>...</code> está disponible a partir de PHP 7.4.0. Esto también se llama
el operador de propagación.
</para>
<para>
Es posible expandir múltiples veces, y añadir elementos normales antes o después del operador <code>...</code>:
<example>
<title>Desempaquetado simple de arrays</title>
<programlisting role="php">
<![CDATA[
<?php
// Usando sintaxis corta de array.
// También funciona con la sintaxis array().
$arr1 = [1, 2, 3];
$arr2 = [...$arr1]; // [1, 2, 3]
$arr3 = [0, ...$arr1]; // [0, 1, 2, 3]
$arr4 = [...$arr1, ...$arr2, 111]; // [1, 2, 3, 1, 2, 3, 111]
$arr5 = [...$arr1, ...$arr1]; // [1, 2, 3, 1, 2, 3]
function getArr() {
return ['a', 'b'];
}
$arr6 = [...getArr(), 'c' => 'd']; // ['a', 'b', 'c' => 'd']
var_dump($arr1, $arr2, $arr3, $arr4, $arr5, $arr6);
?>
]]>
</programlisting>
</example>
</para>
<para>
El desempaquetado de un array con el operador <code>...</code> sigue la semántica de la función <function>array_merge</function>.
Es decir, las claves de cadena posteriores sobrescriben las anteriores y las claves enteras son renumeradas:
<example>
<title>Desempaquetado de arrays con clave duplicada</title>
<programlisting role="php">
<![CDATA[
<?php
// clave de cadena
$arr1 = ["a" => 1];
$arr2 = ["a" => 2];
$arr3 = ["a" => 0, ...$arr1, ...$arr2];
var_dump($arr3); // ["a" => 2]
// clave entera
$arr4 = [1, 2, 3];
$arr5 = [4, 5, 6];
$arr6 = [...$arr4, ...$arr5];
var_dump($arr6); // [1, 2, 3, 4, 5, 6]
// Que es [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6]
// donde las claves enteras originales no han sido retenidas.
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
Las claves que no son ni enteras ni cadenas lanzan un <classname>TypeError</classname>.
Tales claves solo pueden ser generadas por un objeto <interfacename>Traversable</interfacename>.
</para>
</note>
<note>
<para>
Antes de PHP 8.1, el desempaquetado de un array que tiene una clave de cadena no es soportado:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$arr1 = [1, 2, 3];
$arr2 = ['a' => 4];
$arr3 = [...$arr1, ...$arr2];
// Error fatal: Error no capturado: No se puede desempaquetar un array con claves de cadena en example.php:5
$arr4 = [1, 2, 3];
$arr5 = [4, 5];
$arr6 = [...$arr4, ...$arr5]; // funciona. [1, 2, 3, 4, 5]
?>
]]>
</programlisting>
</informalexample>
</note>
</sect2>
<sect2 xml:id="language.types.array.examples">
<title>Ejemplos</title>
<para>
El tipo array en PHP es muy versátil. Aquí hay algunos ejemplos:
</para>
<example>
<title>Versatilidad de arrays</title>
<programlisting role="php">
<![CDATA[
<?php
// Esto:
$a = array( 'color' => 'red',
'taste' => 'sweet',
'shape' => 'round',
'name' => 'apple',
4 // la clave será 0
);
$b = array('a', 'b', 'c');
var_dump($a, $b);
// . . .es completamente equivalente a esto:
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name'] = 'apple';
$a[] = 4; // la clave será 0
$b = array();
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// Después de que el código anterior sea ejecutado, $a será el array
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
// 'name' => 'apple', 0 => 4), y $b será el array
// array(0 => 'a', 1 => 'b', 2 => 'c'), o simplemente array('a', 'b', 'c').
var_dump($a, $b);
?>
]]>
</programlisting>
</example>
<example>
<title>Usando array()</title>
<programlisting role="php">
<![CDATA[
<?php
// Array como (mapa de propiedades)
$map = array( 'version' => 4,
'OS' => 'Linux',
'lang' => 'english',
'short_tags' => true
);
var_dump($map);
// claves estrictamente numéricas
// esto es lo mismo que array(0 => 7, 1 => 8, ...)
$array = array( 7,
8,
0,
156,
-10
);
var_dump($array);
$switching = array( 10, // clave = 0
5 => 6,
3 => 7,
'a' => 4,
11, // clave = 6 (el máximo de los índices enteros era 5)
'8' => 2, // clave = 8 (¡entero!)
'02' => 77, // clave = '02'
0 => 12 // el valor 10 será sobrescrito por 12
);
var_dump($switching);
// array vacío
$empty = array();
var_dump($empty);
?>
]]>
<!-- TODO ejemplo de
- sobrescritura de claves
- uso de vars/funciones como clave/valores
- advertencia sobre referencias
-->
</programlisting>
</example>
<example xml:id="language.types.array.examples.loop">
<title>Colección</title>
<programlisting role="php">
<![CDATA[
<?php
$colors = array('red', 'blue', 'green', 'yellow');
foreach ($colors as $color) {
echo "¿Te gusta $color?\n";
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
¿Te gusta red?
¿Te gusta blue?
¿Te gusta green?
¿Te gusta yellow?
]]>
</screen>
</example>
<para>
Cambiar los valores del <type>array</type> directamente es posible
pasándolos por referencia.
</para>
<example xml:id="language.types.array.examples.changeloop">
<title>Cambiar elemento en el bucle</title>
<programlisting role="php">
<![CDATA[
<?php
$colors = array('red', 'blue', 'green', 'yellow');
foreach ($colors as &$color) {
$color = mb_strtoupper($color);
}
unset($color); /* asegurar que las siguientes escrituras a
$color no modificarán el último elemento del array */
print_r($colors);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[0] => RED
[1] => BLUE
[2] => GREEN
[3] => YELLOW
)
]]>
</screen>
</example>
<para>
Este ejemplo crea un array basado en uno.
</para>
<example>
<title>Índice basado en uno</title>
<programlisting role="php">
<![CDATA[
<?php
$firstquarter = array(1 => 'January', 'February', 'March');
print_r($firstquarter);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[1] => January
[2] => February
[3] => March
)
]]>
</screen>
</example>
<example>
<title>Llenando un array</title>
<programlisting role="php">
<![CDATA[
<?php
// llenar un array con todos los elementos de un directorio
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
$files[] = $file;
}
closedir($handle);
var_dump($files);
?>
]]>
</programlisting>
</example>
<para>
Los <type>array</type>s están ordenados. El orden puede ser cambiado usando varias
funciones de ordenamiento. Vea la sección de <link linkend="ref.array">funciones de array</link>
para más información. La función <function>count</function> puede ser
usada para contar el número de elementos en un <type>array</type>.
</para>
<example>
<title>Ordenando un array</title>
<programlisting role="php" annotations="non-interactive">
<![CDATA[
<?php
sort($files);
print_r($files);
?>
]]>
</programlisting>
</example>
<para>
Debido a que el valor de un <type>array</type> puede ser cualquier cosa, también puede ser
otro <type>array</type>. Esto permite la creación de arrays recursivos y
multidimensionales.
</para>
<example>
<title>Arrays recursivos y multidimensionales</title>
<programlisting role="php">
<![CDATA[
<?php
$fruits = array ( "fruits" => array ( "a" => "orange",
"b" => "banana",
"c" => "apple"
),
"numbers" => array ( 1,
2,
3,
4,
5,
6
),
"holes" => array ( "first",
5 => "second",
"third"
)
);
var_dump($fruits);
// Algunos ejemplos para direccionar valores en el array anterior
echo $fruits["holes"][5]; // imprime "second"
echo $fruits["fruits"]["a"]; // imprime "orange"
unset($fruits["holes"][0]); // elimina "first"
// Crear un nuevo array multidimensional
$juices["apple"]["green"] = "good";
var_dump($juices);
?>
]]>
</programlisting>
</example>
<para>
La asignación de <type>array</type> siempre implica la copia de valores. Use el
<link linkend="language.operators">operador de referencia</link> para copiar un
<type>array</type> por referencia.
</para>
<example>
<title>Copiado de arrays</title>
<programlisting role="php">
<![CDATA[
<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 es cambiado,
// $arr1 sigue siendo array(2, 3)
$arr3 = &$arr1;
$arr3[] = 4; // ahora $arr1 y $arr3 son los mismos
var_dump($arr1, $arr2, $arr3);
?>
]]>
</programlisting>
</example>
</sect2>
</sect1>
<!-- 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
-->