mirror of
https://github.com/php/doc-es.git
synced 2026-03-25 16:02:13 +01:00
git-svn-id: https://svn.php.net/repository/phpdoc/es/trunk@337320 c90b9560-bf6c-de11-be94-00142212c4b1
581 lines
18 KiB
XML
581 lines
18 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: 97c50278a64ae5e3e646e36c1f7926c1bb2e689a Maintainer: seros Status: ready -->
|
|
<!-- Reviewed: no Maintainer: yago -->
|
|
<chapter xml:id="language.references" xmlns="http://docbook.org/ns/docbook">
|
|
<title>Referencias Explicadas</title>
|
|
|
|
<sect1 xml:id="language.references.whatare">
|
|
<title>¿Qué son las Referencias?</title>
|
|
<simpara>
|
|
Las Referencias en PHP son medios de acceder al mismo contenido de una variable
|
|
mediante diferentes nombres. No son como los punteros de C; por ejemplo,
|
|
no se puede realizar aritmética de punteros con ellas, realmente
|
|
no son direcciones de memoria, etc. Véase
|
|
<xref linkend="language.references.arent" /> para más
|
|
información. Las referencias son alias de la tabla de símbolos. Observe que en
|
|
PHP el nombre de la variable y el contenido de la variable son cosas diferentes, por lo que el mismo
|
|
contenido puede tener diferentes nombres. La analogía más próxima es con
|
|
los archivos y los nombres de archivos de Unix - los nombres de variables son entradas de directorio,
|
|
mientras que el contenido de las variables es el archivo en sí. Las referencias se pueden
|
|
vincular a enlaces duros en sistemas de archivos Unix.
|
|
</simpara>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.references.whatdo">
|
|
<title>¿Qué hacen las referencias?</title>
|
|
<para>
|
|
Hay tres operaciones básicas que se realizan usando referencias:
|
|
<link linkend="language.references.whatdo.assign">asignar por
|
|
referencia</link>, <link linkend="language.references.whatdo.pass">pasar por
|
|
referencia</link>,
|
|
y <link linkend="language.references.whatdo.return">devolver por
|
|
referencia</link>. En esta sección se dará una introducción a estas
|
|
operaciones, con enlaces para una lectura complementaria.
|
|
</para>
|
|
<sect2 xml:id="language.references.whatdo.assign">
|
|
<title>Asignar por Referencia</title>
|
|
<para>
|
|
En la primera de estas operaciones, las referencias de PHP permiten hacer que dos
|
|
variables hagan referencia al mismo contenido. Es decir, cuando se hace:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a =& $b;
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
significa que <varname>$a</varname> y <varname>$b</varname>
|
|
apuntan al mismo contenido.
|
|
<note>
|
|
<para>
|
|
<varname>$a</varname> y <varname>$b</varname> aquí son completamente
|
|
iguales. <varname>$a</varname> no está apuntando a
|
|
<varname>$b</varname> o viceversa.
|
|
<varname>$a</varname> y <varname>$b</varname> están apuntando al
|
|
mismo lugar.
|
|
</para>
|
|
</note>
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Si se asigna, pasa, o devuelve una variable no definida por referencia,
|
|
la variable se creará.
|
|
<example>
|
|
<title>Usar referencias con variables no definidas</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>
|
|
Se puede usar la misma sintaxis con funciones que devuelven
|
|
referencias y con el operador <literal>new</literal> (desde PHP
|
|
4.0.4 y anterior a PHP 5.0.0):
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$foo =& find_var($bar);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
Desde PHP 5, <link linkend="language.oop5.basic.new">new</link>
|
|
devuelve una referencia automáticamente, por lo que
|
|
usar <literal>=&</literal> en este contexto es obsoleto y
|
|
produce un mensaje <constant>E_DEPRECATED</constant> en PHP 5.3 y
|
|
posteriores, y un mensaje <constant>E_STRICT</constant> en versiones anteriores.
|
|
A partir de PHP 7.0 es sintácticamente inválido.
|
|
(Técnicamente, la diferencia es que, en PHP 5, las variables de objetos, como
|
|
los recursos, son meros punteros a la información del objeto actual, por lo que estas referencias
|
|
a objetos no son "referencias" en el mismo sentido usado antes (alias).
|
|
Para más información, véase <link linkend="language.oop5.references">Objetos
|
|
y referencias</link>.)
|
|
</para>
|
|
<warning>
|
|
<para>
|
|
Si se asigna una referencia a una varible declarada <literal>global</literal>
|
|
dentro de una función, la referencia será visible sólo dentro de la función.
|
|
Se puede evitar esto usando la matriz <varname>$GLOBALS</varname>.
|
|
<example>
|
|
<title>Refenciar variables globales dentro de funciones</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$var1 = "Variable de ejemplo";
|
|
$var2 = "";
|
|
|
|
function referencias_globales($usar_globals)
|
|
{
|
|
global $var1, $var2;
|
|
if (!$usar_globals) {
|
|
$var2 =& $var1; // visible sólo dentro de la función
|
|
} else {
|
|
$GLOBALS["var2"] =& $var1; // visible también en el contexto global
|
|
}
|
|
}
|
|
|
|
referencias_globales(false);
|
|
echo "var2 está establecida a '$var2'\n"; // var2 está establecida a ''
|
|
referencias_globales(true);
|
|
echo "var2 está establecida a '$var2'\n"; // var2 está establecida a 'Variable de ejemplo'
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
Piense en <literal>global $var;</literal> como simplificación de <literal>$var
|
|
=& $GLOBALS['var'];</literal>. De este modo, al asignar otra referencia
|
|
a <literal>$var</literal> sólo cambia la referencia de la variable local.
|
|
</para>
|
|
</warning>
|
|
<note>
|
|
<para>
|
|
Si se asigna un valor a una variable con referencias en una
|
|
sentencia &foreach;, también se modifican las referencias.
|
|
<example>
|
|
<title>Referencias y la sentencia foreach</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$ref = 0;
|
|
$fila =& $ref;
|
|
foreach (array(1, 2, 3) as $fila) {
|
|
// hacer algo
|
|
}
|
|
echo $ref; // 3 - último elemento de la matriz iterada
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</note>
|
|
<para>
|
|
Mientras que no sea estrictamente una asignación por referencia, las expresiones creadas
|
|
con el constructor de lenguaje
|
|
<link linkend="function.array"><literal>array()</literal></link> también pueden
|
|
comportarse como tales prefijando <literal>&</literal> al elemento del array
|
|
a añadir. 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>
|
|
Observe, sin embargo, que las referencias dentro de arrays son potencialmente peligrosas.
|
|
Realizar una asignación normal (no por referencia) con una referencia en el
|
|
lado derecho no convierte el lado izquierdo en una referencia, pero las referencias
|
|
dentro de arrays son conservadas en estas asignaciones normales. Esto también se aplica
|
|
a las llamadas a funciones donde el array es 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 cambia $a o $b
|
|
|
|
/* Asignación de variables de array */
|
|
$arr = array(1);
|
|
$a =& $arr[0]; // $a y $arr[0] son el mismo conjunto de referencias
|
|
$arr2 = $arr; // ¡no es una asignación por referencia!
|
|
$arr2[0]++;
|
|
/* $a == 2, $arr == array(2) */
|
|
/* ¡El contenido de $arr se cambia incluso si no es una referencia! */
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
En otras palabras, el comportamiento de las referencias de arrays está definido en una
|
|
base elemento-por-elemento; el comportamiento de las referencias de elementos individuales
|
|
está desasociado del estado de la referencia del array contenedor.
|
|
</para>
|
|
</sect2>
|
|
<sect2 xml:id="language.references.whatdo.pass">
|
|
<title>Pasar por Referencia</title>
|
|
<para>
|
|
Lo segundo que hacen las referencias es pasar variables por
|
|
referencia. Esto se lleva a cabo haciendo que una variable local en una función
|
|
y una variable en el ámbito de la llamada referencien al mismo
|
|
contenido. Ejemplo:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function foo(&$var)
|
|
{
|
|
$var++;
|
|
}
|
|
|
|
$a=5;
|
|
foo($a);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
hará que <varname>$a</varname> sea 6. Esto sucede porque en
|
|
la función <varname>foo</varname> la variable
|
|
<varname>$var</varname> hace referencia al mismo contenido que
|
|
<varname>$a</varname>. Para más información sobre esto, lea
|
|
la sección <link linkend="language.references.pass">pasar por
|
|
referencia</link>.
|
|
</para>
|
|
</sect2>
|
|
<sect2 xml:id="language.references.whatdo.return">
|
|
<title>Devolver por Referencia</title>
|
|
<para>
|
|
Lo tercero que hacen las referncias es <link
|
|
linkend="language.references.return">devolver por referencia</link>.
|
|
</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.references.arent">
|
|
<title>¿Qué NO son las Referencias?</title>
|
|
<para>
|
|
Como se dijo antes, las referencias no son punteros. Es decir, la
|
|
siguiente construcción no hará lo que se esperaba:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function foo(&$var)
|
|
{
|
|
$var =& $GLOBALS["baz"];
|
|
}
|
|
foo($bar);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<simpara>
|
|
Lo que sucede es que <varname>$var</varname> en
|
|
<varname>foo</varname> será ligada con
|
|
<varname>$bar</varname> en la llamada, pero entonces
|
|
será religada con <varname>$GLOBALS["baz"]</varname>. No hay forma
|
|
de ligar <varname>$bar</varname> en el ámbito de la llamada a otra cosa
|
|
usando el mecanismo de referencia, ya que <varname>$bar</varname> no está
|
|
disponible en la función <varname>foo</varname> (está representada por
|
|
<varname>$var</varname>, pero <varname>$var</varname> sólo tiene
|
|
el contenido de la variable y no la vinculación nombre-a-valor en la tabla
|
|
de símbolos de llamada).
|
|
Se puede usar <link linkend="language.references.return">devolver
|
|
referencias</link> para referencias variables seleccionadas por la función.
|
|
</simpara>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.references.pass">
|
|
<title>Pasar por Referencia</title>
|
|
<para>
|
|
Se puede pasar una variable por referencia a una función y así hacer que la función
|
|
pueda modificar la variable. La sintaxis es la siguiente:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function foo(&$var)
|
|
{
|
|
$var++;
|
|
}
|
|
|
|
$a=5;
|
|
foo($a);
|
|
// $a es 6 aquí
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
<note>
|
|
<simpara>
|
|
No existe ningún signo de referencia en una llamada a una función - sólo en
|
|
la definición de la función. Las definiciones de funciones por sí solas son suficientes para
|
|
pasar correctamente el argumento por referencia. A partir de PHP 5.3.0,
|
|
se obtendrá una advertencia diciendo que "call-time pass-by-reference" (pasar por referencia
|
|
en tiempo de llamada) está obsoleto cuando se use & en <literal>foo(&$a);</literal>.
|
|
A partir de PHP 5.4.0, el paso por referencia en tiempo de llamada ha sido eliminado,
|
|
por lo que su uso emitirá un error fatal.
|
|
</simpara>
|
|
</note>
|
|
</para>
|
|
<para>
|
|
Se puede pasar por referencia lo siguiente:
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
Variables, esto es, <literal>foo($a)</literal>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Nuevas declaraciones, esto es, <literal>foo(new foobar())</literal>
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Referencias devueltas desde funciones, esto es:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function foo(&$var)
|
|
{
|
|
$var++;
|
|
}
|
|
function &bar()
|
|
{
|
|
$a = 5;
|
|
return $a;
|
|
}
|
|
foo(bar());
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
Vea más sobre <link
|
|
linkend="language.references.return">devolver por referencia</link>.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
<para>
|
|
Ninguna otra expresión debería pasarse por referencia, ya que el
|
|
resultado no está definido. Por ejemplo, los siguientes ejemplos de pasar
|
|
por referencia no son válidos:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function foo(&$var)
|
|
{
|
|
$var++;
|
|
}
|
|
function bar() // Observe que falta el &
|
|
{
|
|
$a = 5;
|
|
return $a;
|
|
}
|
|
foo(bar()); // Produce un error fatal a partir de PHP 5.0.5,un aviso de estándar estricto
|
|
// a partir de PHP 5.1.1, y un aviso a partir de PHP 7.0.0
|
|
|
|
foo($a = 5); // Expresión, no una variable
|
|
foo(5); // Produce un error fatal
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
Estos requerimientos son para PHP 4.0.4 y posterior.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.references.return">
|
|
<title>Devolver Referencias</title>
|
|
<para>
|
|
Devolver por referencia es útil cuando se quiere usar una función
|
|
para encontrar a qué variable debería estar vinculada una referencia.
|
|
<emphasis>No</emphasis> use devolver por referencia para aumentar el rendimiento.
|
|
El motor optimizará automáticamente esto por sí mismo. Hay que devolver
|
|
referencias sólo cuando se tenga una razón técnicamente válida para hacerlo. Para
|
|
devolver referencias use esta sintaxis:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class foo {
|
|
public $valor = 42;
|
|
|
|
public function &obtenerValor() {
|
|
return $this->valor;
|
|
}
|
|
}
|
|
|
|
$obj = new foo;
|
|
$miValor = &$obj->obtenerValor(); // $miValor es una referencia a $obj->valor, que es 42.
|
|
$obj->valor = 2;
|
|
echo $miValor; // imprime el nuevo valor de $obj->valor, esto es, 2.
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
En este ejemplo, la propiedad del objeto devuelto por la
|
|
función <varname>obtenerValor</varname> debería estar establecida, no la
|
|
copia, como si estuviera sin usar la sintaxis de referencia.
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
A diferencia de pasar un parámetro, aquí se tiene que usar
|
|
<literal>&</literal> en ambos lugares - para indicar que se
|
|
quiere devolver por referencia, no una copia, y para indicar que
|
|
la vinculación por referencia, en vez de la asignación normal, debería ser hecha
|
|
para <varname>$miValor</varname>.
|
|
</simpara>
|
|
</note>
|
|
<note>
|
|
<simpara>
|
|
Si se intenta devolver una referencia desde una función con la sintaxis:
|
|
<literal>return ($this->valor);</literal>, <emphasis>no</emphasis>
|
|
funcionará ya que se está intentando devolver el resultado de una
|
|
<emphasis>expresión</emphasis>, y no de una variable, por referencia. Sólo se
|
|
puede devolver variables por referencia desde una función - nada más.
|
|
Desde PHP 4.4.0 en la rama PHP 4, y PHP 5.1.0 en la rama PHP 5, se
|
|
emite un error <constant>E_NOTICE</constant> si el código intenta devolver
|
|
una expresión dinámica o un resultado del operador <literal>new</literal>.
|
|
</simpara>
|
|
</note>
|
|
<para>
|
|
Para usar la referencia retornada, se debe usar la asignación por referencia:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function &collector() {
|
|
static $collection = array();
|
|
return $collection;
|
|
}
|
|
$collection = &collector();
|
|
$collection[] = 'foo';
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
Para pasar la referencia retornada a otra función que espera una referencia
|
|
se puede usar 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>
|
|
Observe que <literal>array_push(&collector(), 'foo');</literal>
|
|
<emphasis>no</emphasis> funcionará, resultará en un error fatal.
|
|
</simpara>
|
|
</note>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.references.unset">
|
|
<title>Destruir Referencias</title>
|
|
<para>
|
|
Cuando se destruye una referencia, se rompe el vínculo entre
|
|
el nombre de la variable y el contenido de la variable. Esto no significa que
|
|
el contenido de la variable sea destruida. Por ejemplo:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = 1;
|
|
$b =& $a;
|
|
unset($a);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
no destruirá <varname>$b</varname>, sólo <varname>$a</varname>.
|
|
</para>
|
|
<simpara>
|
|
De nuevo, podría ser útil pensar en esto como análogo a una llamada
|
|
a <command>unlink</command> de Unix.
|
|
</simpara>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.references.spot">
|
|
<title>Ubicar las Referencias</title>
|
|
<simpara>
|
|
Muchas construcciones sintácticas de PHP están implementadas mediante el mecanismo
|
|
de referencia, por lo que todo lo mencionado aquí sobre la vinculación de referencias también
|
|
se aplica a estas construcciones. Algunas construcciones, como pasar y
|
|
devolver por referencia, han sido mencionadas antes. Otras construcciones que
|
|
usan referencias son:
|
|
</simpara>
|
|
|
|
<sect2 xml:id="references.global">
|
|
<title>Referencias globales</title>
|
|
<para>
|
|
Cuando se declara una variable como <command>global $var</command>,
|
|
de hecho se está creando una referencia a una variable global. Es decir,
|
|
esto es lo mismo que:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$var =& $GLOBALS["var"];
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<simpara>
|
|
Esto también significa que al destruir <varname>$var</varname>
|
|
no se destruirá la variable global.
|
|
</simpara>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="references.this">
|
|
<title><literal>$this</literal></title>
|
|
<simpara>
|
|
En un método de un objeto, <varname>$this</varname> es siempre una referencia
|
|
al objeto que realiza la llamada.
|
|
</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:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|