mirror of
https://github.com/php/doc-es.git
synced 2026-03-23 23:12:09 +01:00
635 lines
17 KiB
XML
635 lines
17 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: 9463e5b660c4883b91a30f07ff68731bbcc48346 Maintainer: PhilDaiguille Status: ready -->
|
|
<!-- Reviewed: no -->
|
|
<!-- CREDITS: DAnnebicque -->
|
|
|
|
<chapter xml:id="language.references" xmlns="http://docbook.org/ns/docbook">
|
|
<title>Las referencias</title>
|
|
<sect1 xml:id="language.references.whatare">
|
|
<title>¿Qué es una referencia?</title>
|
|
<simpara>
|
|
En PHP, las referencias son una forma de acceder al contenido de una misma
|
|
variable utilizando varios nombres. Las referencias no son como los
|
|
punteros en C: no se pueden realizar operaciones aritméticas de punteros
|
|
sobre ellas, no son direcciones de memoria, etc.
|
|
Se puede consultar
|
|
<xref linkend="language.references.arent" /> para más información.
|
|
De hecho, las referencias son alias en la
|
|
<link linkend="features.gc.refcounting-basics">tabla de símbolos</link>.
|
|
Tenga en cuenta que en PHP, el nombre de una variable y su contenido son dos
|
|
nociones distintas, lo que hace que se puedan dar
|
|
varios nombres al mismo contenido.
|
|
Se puede hacer la analogía con los ficheros bajo Unix, y sus nombres:
|
|
los nombres de las variables son las entradas en un directorio, mientras
|
|
que el contenido de la variable es el fichero en sí mismo.
|
|
Las referencias en PHP pueden entonces ser consideradas similares
|
|
a los enlaces bajo Unix.
|
|
</simpara>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.references.whatdo">
|
|
<title>¿Qué hacen las referencias?</title>
|
|
<para>
|
|
Existen tres principales usos de las referencias:
|
|
la <link linkend="language.references.whatdo.assign">asignación por
|
|
referencia</link>, el <link linkend="language.references.whatdo.pass">paso
|
|
por referencia</link>
|
|
y el <link linkend="language.references.whatdo.return">retorno por
|
|
referencia</link>. Esta sección introducirá estas operaciones, con enlaces
|
|
a más detalles.
|
|
</para>
|
|
<sect2 xml:id="language.references.whatdo.assign">
|
|
<title>Asignación por referencia</title>
|
|
<para>
|
|
En este primer caso, las referencias PHP permiten que dos variables referencien el mismo contenido.
|
|
Por ejemplo:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$a =& $b;
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
Esta escritura indica que <varname>$a</varname> y <varname>$b</varname>
|
|
apuntan al mismo contenido.
|
|
<note>
|
|
<para>
|
|
<varname>$a</varname> y <varname>$b</varname> son completamente
|
|
iguales aquí: no es <varname>$a</varname> quien apunta a
|
|
<varname>$b</varname>, o viceversa. Son <varname>$a</varname>
|
|
y <varname>$b</varname> quienes apuntan al mismo contenido.
|
|
</para>
|
|
</note>
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Si se asigna, pasa o devuelve una variable indefinida por referencia,
|
|
se creará automáticamente.
|
|
<example>
|
|
<title>Uso de referencias con variables indefinidas</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
function foo(&$var) {}
|
|
|
|
foo($a); // $a es "creada" y asignada a NULL
|
|
|
|
$b = array();
|
|
foo($b['b']);
|
|
var_dump(array_key_exists('b', $b)); // bool(true)
|
|
|
|
$c = new stdClass();
|
|
foo($c->d);
|
|
var_dump(property_exists($c, 'd')); // bool(true)
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</note>
|
|
<para>
|
|
La misma sintaxis puede ser utilizada con las funciones que
|
|
devuelven referencias:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$foo =& find_var($bar);
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Utilizar la misma sintaxis con una función que <emphasis>no</emphasis>
|
|
devuelve por referencia generará un error, al igual que utilizarla con el
|
|
resultado del operador <link linkend="language.oop5.basic.new">new</link>.
|
|
Aunque los objetos se pasan como punteros, esto no es idéntico a las referencias como se explica en la sección los
|
|
<link linkend="language.oop5.references">Objetos y referencias</link>.
|
|
</para>
|
|
<warning>
|
|
<para>
|
|
Si se asigna una referencia a una variable declarada como <literal>global</literal>
|
|
en una función, la referencia solo será visible dentro de la función.
|
|
Se puede evitar esto utilizando el array <varname>$GLOBALS</varname>.
|
|
<example>
|
|
<title>Referenciar variables globales desde funciones</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$var1 = "Variable Ejemplo";
|
|
$var2 = "";
|
|
|
|
function global_references($use_globals)
|
|
{
|
|
global $var1, $var2;
|
|
|
|
if (!$use_globals) {
|
|
$var2 =& $var1; // visible solo en la función
|
|
} else {
|
|
$GLOBALS["var2"] =& $var1; // visible también en el contexto global
|
|
}
|
|
}
|
|
|
|
global_references(false);
|
|
echo "var2 está definido como '$var2'\n"; // var2 está definido como ''
|
|
|
|
global_references(true);
|
|
echo "var2 está definido como '$var2'\n"; // var2 está definido como 'Variable Ejemplo'
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
Vea <literal>global $var;</literal> como un atajo para <literal>$var
|
|
=& $GLOBALS['var'];</literal>. Por lo tanto, asignar otra referencia a
|
|
<literal>$var</literal> solo modifica la referencia local de la variable.
|
|
</para>
|
|
</warning>
|
|
<note>
|
|
<para>
|
|
Si se asigna un valor a una variable que tiene referencias en una estructura
|
|
&foreach;, las referencias también serán modificadas.
|
|
<example>
|
|
<title>Referencias y estructura foreach</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$ref = 0;
|
|
$row =& $ref;
|
|
|
|
foreach (array(1, 2, 3) as $row) {
|
|
// hacer algo
|
|
}
|
|
|
|
echo $ref; // 3 - el último elemento del array iterado
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</note>
|
|
<para>
|
|
Aunque no es estrictamente una asignación por referencia, las expresiones
|
|
creadas con la estructura de lenguaje
|
|
<link linkend="function.array"><literal>array()</literal></link> pueden también
|
|
comportarse como tales, prefijando con <literal>&</literal> el elemento del array.
|
|
Aquí hay un ejemplo:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$a = 1;
|
|
$b = array(2, 3);
|
|
$arr = array(&$a, &$b[0], &$b[1]);
|
|
$arr[0]++;
|
|
$arr[1]++;
|
|
$arr[2]++;
|
|
/* $a == 2, $b == array(3, 4); */
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Note que las referencias dentro de los arrays pueden resultar
|
|
peligrosas. Utilizar una asignación normal (no por referencia) con una
|
|
referencia a la derecha del operador no transforma la parte izquierda de la asignación
|
|
en referencia, pero las referencias dentro de los arrays son preservadas. Esto
|
|
se aplica también a las llamadas de funciones con un array pasado por valor. Ejemplo:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
/* Asignación de variables escalares */
|
|
$a = 1;
|
|
$b =& $a;
|
|
$c = $b;
|
|
$c = 7; // $c no es una referencia; no hay cambio en $a o $b
|
|
|
|
/* Asignación de variables de tipo array */
|
|
$arr = array(1);
|
|
$a =& $arr[0]; // $a y $arr[0] son referencias al mismo valor
|
|
$arr2 = $arr; // NO es una asignación por referencia!
|
|
$arr2[0]++;
|
|
/* $a == 2, $arr == array(2) */
|
|
/* ¡Los contenidos de $arr son cambiados aunque no fuera una referencia! */
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
En otras palabras, desde el punto de vista de las referencias, el comportamiento de los arrays
|
|
está definido elemento por elemento; el comportamiento
|
|
de cada elemento
|
|
es independiente del estado de referencia del array que los contiene.
|
|
</para>
|
|
</sect2>
|
|
<sect2 xml:id="language.references.whatdo.pass">
|
|
<title>Paso por referencia</title>
|
|
<para>
|
|
El segundo interés de las referencias es
|
|
permitir pasar variables por referencia. Esto se realiza haciendo
|
|
referenciar el mismo contenido por una variable local a una función y por una
|
|
variable del contexto llamante.
|
|
Por ejemplo:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
function foo(&$var) {
|
|
$var++;
|
|
}
|
|
$a=5;
|
|
foo($a);
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
Después de la ejecución de esta porción de código, <varname>$a</varname> vale 6.
|
|
Esto se debe a que, en la función <varname>foo</varname>, la
|
|
variable <varname>$var</varname> apunta al mismo contenido que
|
|
<varname>$a</varname>.
|
|
Para más información sobre este tema, se puede consultar la sección
|
|
<link linkend="language.references.pass">paso por referencia</link>.
|
|
</para>
|
|
</sect2>
|
|
<sect2 xml:id="language.references.whatdo.return">
|
|
<title>Retorno por referencia</title>
|
|
<para>
|
|
El tercer interés de las referencias es permitir el
|
|
<link linkend="language.references.return">retorno de valores por
|
|
referencia</link>.
|
|
</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.references.arent">
|
|
<title>Lo que las referencias no son</title>
|
|
<para>
|
|
Como se ha visto anteriormente, las referencias no
|
|
son punteros. Esto significa que el script siguiente no hará
|
|
lo que se espera:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
function foo(&$var) {
|
|
$var =& $GLOBALS["baz"];
|
|
}
|
|
|
|
foo($bar);
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<simpara>
|
|
Aquí, la variable <varname>$var</varname> en la función <varname>foo</varname> estará ligada
|
|
a <varname>$bar</varname> en el llamante, pero luego estará ligada a
|
|
<varname>$GLOBALS["baz"]</varname>.
|
|
No es posible ligar <varname>$bar</varname> a otra cosa utilizando
|
|
el mecanismo de referencias, ya que <varname>$bar</varname> no es accesible en la
|
|
función <varname>foo</varname> (aunque está representada por <varname>$var</varname>,
|
|
<varname>$var</varname> solo hace referencia al valor, y no tiene una ligadura en la
|
|
<link linkend="features.gc.refcounting-basics">tabla de símbolos</link> del llamante).
|
|
Se puede utilizar el <link linkend="language.references.return">retorno por
|
|
referencia</link> para referenciar variables seleccionadas por la función.
|
|
</simpara>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.references.pass">
|
|
<title>Paso por referencia</title>
|
|
<para>
|
|
Se puede pasar una variable por referencia a una función, de
|
|
manera que esta pueda modificarla.
|
|
La sintaxis es la siguiente:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
function foo(&$var) {
|
|
$var++;
|
|
}
|
|
$a=5;
|
|
|
|
foo ($a);
|
|
// $a vale 6 ahora
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
<note>
|
|
<simpara>
|
|
No hay signo de referencia en la llamada de la
|
|
función, solo en su definición. La definición de la
|
|
función en sí misma es suficiente para pasar correctamente
|
|
argumentos por referencia.
|
|
</simpara>
|
|
</note>
|
|
</para>
|
|
<para>
|
|
Los siguientes datos pueden ser pasados por referencia:
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
Una variable, como en <literal>foo($a)</literal>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Una referencia devuelta por una función:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
function foo(&$var)
|
|
{
|
|
$var++;
|
|
}
|
|
|
|
function &bar()
|
|
{
|
|
$a = 5;
|
|
return $a;
|
|
}
|
|
|
|
foo(bar());
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
Para más información, ver los detalles en
|
|
<link linkend="language.references.return">retorno por
|
|
referencia</link>.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
<para>
|
|
Todas las otras expresiones no deben ser pasadas por
|
|
referencia, ya que el resultado será indefinido. Por ejemplo,
|
|
los siguientes pasos por referencia son inválidos:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
function foo(&$var)
|
|
{
|
|
$var++;
|
|
}
|
|
|
|
function bar() // Note la ausencia de &
|
|
{
|
|
$a = 5;
|
|
return $a;
|
|
}
|
|
|
|
foo(bar()); // Produce una notificación
|
|
|
|
foo($a = 5); // Expresión, no una variable
|
|
foo(5); // Produce un error fatal
|
|
|
|
class Foobar{}
|
|
|
|
foo(new Foobar()) // Produce una notificación desde PHP 7.0.7
|
|
// Notificación: Solo las variables deben ser pasadas por referencia.
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.references.return">
|
|
<title>Devolver referencias</title>
|
|
<para>
|
|
Devolver referencias es útil cuando se
|
|
quiere utilizar una función para determinar a qué variable
|
|
debe estar ligada una referencia.
|
|
No utilice <emphasis>no</emphasis>
|
|
el retorno por referencia para mejorar el rendimiento,
|
|
el motor es suficientemente robusto para optimizar esto
|
|
internamente. Devuelva referencias solo
|
|
cuando haya buenas razones técnicas
|
|
para hacerlo. Para devolver referencias, utilice esta sintaxis:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
class Foo
|
|
{
|
|
public $value = 42;
|
|
|
|
public function &getValue()
|
|
{
|
|
return $this->value;
|
|
}
|
|
}
|
|
|
|
$obj = new Foo();
|
|
$myValue = &$obj->getValue(); // $myValue es una referencia de $obj->value, que vale 42.
|
|
$obj->value = 2;
|
|
echo $myValue; // muestra el nuevo valor de $obj->value, es decir, 2.
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
En este ejemplo, se asigna un valor a la propiedad del objeto
|
|
devuelta por la función <varname>getValue</varname>, y no a su copia,
|
|
como sería el caso si no se hubiera utilizado la sintaxis de referencia.
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
A diferencia del paso de parámetro, aquí, se debe utilizar
|
|
<literal>&</literal> en ambos lugares, tanto para
|
|
indicar que se devuelve por referencia (no por copia), como
|
|
para indicar que también se asigna por referencia (no por copia
|
|
tampoco) para la variable <varname>$myValue</varname>.
|
|
</simpara>
|
|
</note>
|
|
<note>
|
|
<simpara>
|
|
Si se intenta devolver una referencia desde una función
|
|
con la sintaxis: <literal>return ($this->value);</literal>,
|
|
esto no funcionará <emphasis>no</emphasis> como
|
|
se espera, y devolverá el resultado de la <emphasis>expresión</emphasis>,
|
|
y no de la variable, por referencia. Solo se pueden devolver
|
|
variables por referencia desde una función, y nada más.
|
|
</simpara>
|
|
</note>
|
|
<para>
|
|
Para utilizar la referencia devuelta, se debe utilizar la asignación
|
|
por referencia:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
function &collector()
|
|
{
|
|
static $collection = array();
|
|
return $collection;
|
|
}
|
|
|
|
$collection = &collector();
|
|
// Ahora, la variable $collection es una variable por referencia que referencia el array static dentro de la función
|
|
|
|
$collection[] = 'foo';
|
|
|
|
print_r(collector());
|
|
// Array
|
|
// (
|
|
// [0] => foo
|
|
// )
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
<note>
|
|
<simpara>
|
|
Si la asignación se realiza sin el símbolo <literal>&</literal>,
|
|
por ejemplo <code>$collection = collector();</code>,
|
|
la variable <varname>$collection</varname> recibirá una copia del valor,
|
|
y no la referencia devuelta por la función.
|
|
</simpara>
|
|
</note>
|
|
Para pasar la referencia devuelta a otra función que espera una referencia,
|
|
se puede utilizar la siguiente sintaxis:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
function &collector()
|
|
{
|
|
static $collection = array();
|
|
return $collection;
|
|
}
|
|
|
|
array_push(collector(), 'foo');
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
Note que <literal>array_push(&collector(), 'foo');</literal>
|
|
<emphasis>no funcionará</emphasis>, y resultará en un error
|
|
fatal.
|
|
</simpara>
|
|
</note>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.references.unset">
|
|
<title>Destruir una referencia</title>
|
|
<para>
|
|
Cuando se destruye una referencia, solo se rompe el enlace entre el nombre de la variable y su contenido.
|
|
Esto no significa que el contenido de la variable sea destruido. Por ejemplo:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$a = 1;
|
|
$b =& $a;
|
|
unset($a);
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
Este ejemplo no destruirá <varname>$b</varname>, solo
|
|
<varname>$a</varname>.
|
|
</para>
|
|
<simpara>
|
|
Una vez más, se puede comparar esta acción con la llamada
|
|
<command>unlink</command> de Unix.
|
|
</simpara>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.references.spot">
|
|
<title>Identificar una referencia</title>
|
|
<simpara>
|
|
Muchas sintaxis de PHP están implementadas a través del
|
|
mecanismo de referencia, y todo lo que se ha visto en cuanto a las ligaduras entre variables
|
|
se aplica a estas sintaxis. Algunas construcciones, como el paso
|
|
de argumentos y el retorno por referencia, han sido mencionadas anteriormente.
|
|
Otras construcciones que utilizan referencias son las siguientes:
|
|
</simpara>
|
|
|
|
<sect2 xml:id="references.global">
|
|
<title>Referencias globales</title>
|
|
<para>
|
|
Cuando se declara una variable como <command>global $var</command>,
|
|
se crea en realidad una referencia a una variable
|
|
global. En otras palabras, esto es lo mismo que:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$var =& $GLOBALS["var"];
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<simpara>
|
|
Esto también significa que destruir la variable <varname>$var</varname> no resultará
|
|
en la destrucción de la variable global.
|
|
</simpara>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
-->
|