mirror of
https://github.com/php/doc-es.git
synced 2026-03-24 07:22:16 +01:00
328 lines
11 KiB
XML
328 lines
11 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- EN-Revision: d6f54016d62904cfd8200604aadd5e3f0d9bad97 Maintainer: PhilDaiguille Status: ready -->
|
|
<!-- Reviewed: no -->
|
|
<sect1 xml:id="language.oop5.overloading" xmlns="http://docbook.org/ns/docbook">
|
|
<title>Sobrecarga mágica</title>
|
|
|
|
<para>
|
|
La sobrecarga mágica en PHP permite "crear" dinámicamente propiedades y métodos. Estas entidades dinámicas son
|
|
tratadas a través de métodos mágicos establecidos que se pueden posicionar
|
|
en una clase para diversos tipos de acciones.
|
|
</para>
|
|
|
|
<para>
|
|
Los métodos mágicos de sobrecarga son llamados durante la interacción
|
|
con propiedades o métodos que no han sido declarados
|
|
o no son <link linkend="language.oop5.visibility">visibles</link>
|
|
en el contexto actual. El resto de esta sección utiliza
|
|
los términos de <quote>propiedades inaccesibles</quote> y de
|
|
<quote>métodos inaccesibles</quote> para referirse a esta
|
|
combinación de declaración y visibilidad.
|
|
</para>
|
|
|
|
<para>
|
|
Todos los métodos mágicos de sobrecarga deben ser definidos como
|
|
<literal>public</literal>.
|
|
</para>
|
|
|
|
<note>
|
|
<para>
|
|
Ninguno de los argumentos de estos métodos mágicos puede ser
|
|
<link linkend="functions.arguments.by-reference">pasado por
|
|
referencia</link>.
|
|
</para>
|
|
</note>
|
|
|
|
<note>
|
|
<para>
|
|
La interpretación PHP de la <quote>sobrecarga</quote> es
|
|
diferente de la de la mayoría de los lenguajes orientados a objetos. La sobrecarga, habitualmente, proporciona la posibilidad de tener
|
|
varios métodos con el mismo nombre pero con una cantidad
|
|
y tipos diferentes de argumentos.
|
|
</para>
|
|
</note>
|
|
|
|
<sect2 xml:id="language.oop5.overloading.members">
|
|
<title>Sobrecarga de propiedades</title>
|
|
|
|
<methodsynopsis xml:id="object.set">
|
|
<modifier>public</modifier> <type>void</type><methodname>__set</methodname>
|
|
<methodparam><type>string</type><parameter>name</parameter></methodparam>
|
|
<methodparam><type>mixed</type><parameter>value</parameter></methodparam>
|
|
</methodsynopsis>
|
|
<methodsynopsis xml:id="object.get">
|
|
<modifier>public</modifier> <type>mixed</type><methodname>__get</methodname>
|
|
<methodparam><type>string</type><parameter>name</parameter></methodparam>
|
|
</methodsynopsis>
|
|
<methodsynopsis xml:id="object.isset">
|
|
<modifier>public</modifier> <type>bool</type><methodname>__isset</methodname>
|
|
<methodparam><type>string</type><parameter>name</parameter></methodparam>
|
|
</methodsynopsis>
|
|
<methodsynopsis xml:id="object.unset">
|
|
<modifier>public</modifier> <type>void</type><methodname>__unset</methodname>
|
|
<methodparam><type>string</type><parameter>name</parameter></methodparam>
|
|
</methodsynopsis>
|
|
|
|
<para>
|
|
<link linkend="object.set">__set()</link> es solicitada al escribir datos
|
|
hacia propiedades inaccesibles (protegidas o privadas) o no existentes.
|
|
</para>
|
|
|
|
<para>
|
|
<link linkend="object.get">__get()</link> es llamada para leer datos desde
|
|
propiedades inaccesibles (protegidas o privadas) o no existentes.
|
|
</para>
|
|
|
|
<para>
|
|
<link linkend="object.isset">__isset()</link> es solicitada cuando
|
|
<function>isset</function> o <function>empty</function> son llamadas sobre
|
|
propiedades inaccesibles (protegidas o privadas) o no existentes.
|
|
</para>
|
|
|
|
<para>
|
|
<link linkend="object.unset">__unset()</link> es invocada cuando
|
|
<function>unset</function> es llamada sobre propiedades inaccesibles
|
|
(protegidas o privadas) o no existentes.
|
|
</para>
|
|
|
|
<para>
|
|
El argumento <varname>$name</varname> es el nombre de la propiedad con la que se interactúa.
|
|
El argumento <varname>$value</varname> del método <link linkend="object.set">__set()</link>
|
|
especifica el valor al que la propiedad <varname>$name</varname> debería ser definida.
|
|
</para>
|
|
|
|
<para>
|
|
La sobrecarga de propiedades solo funciona en contextos de objeto.
|
|
Estos métodos mágicos no serán lanzados en contexto estático.
|
|
Por consiguiente, estos métodos no deberían ser declarados como
|
|
<link linkend="language.oop5.static">estáticos</link>.
|
|
Se lanza un aviso si alguno de los métodos mágicos es declarado como estático.
|
|
</para>
|
|
|
|
<note>
|
|
<para>
|
|
El valor devuelto por <link linkend="object.set">__set()</link>
|
|
es ignorado debido a la forma en que PHP trata el operador de asignación.
|
|
De la misma manera, <link linkend="object.get">__get()</link> nunca es llamada durante
|
|
una asignación encadenada, como esta:
|
|
<literal><![CDATA[ $a = $obj->b = 8; ]]></literal>
|
|
</para>
|
|
</note>
|
|
|
|
<note>
|
|
<para>
|
|
PHP no llamará a un método sobrecargado desde el mismo método sobrecargado.
|
|
Esto significa, por ejemplo, que escribir <code>return $this->foo</code> dentro
|
|
de <link linkend="object.get">__get()</link> devolverá <literal>null</literal>
|
|
y lanzará un <constant>E_WARNING</constant> si no hay una propiedad <literal>foo</literal> definida,
|
|
en lugar de llamar a <link linkend="object.get">__get()</link> una segunda vez.
|
|
Sin embargo, los métodos de sobrecarga pueden invocar otros métodos de sobrecarga de manera implícita
|
|
(por ejemplo, <link linkend="object.set">__set()</link> desencadenando <link linkend="object.get">__get()</link>).
|
|
</para>
|
|
</note>
|
|
|
|
<example>
|
|
<title>Ejemplo de sobrecarga de propiedades con los métodos
|
|
<link linkend="object.get">__get()</link>,
|
|
<link linkend="object.set">__set()</link>,
|
|
<link linkend="object.isset">__isset()</link> y
|
|
<link linkend="object.unset">__unset()</link>
|
|
</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class PropertyTest
|
|
{
|
|
/** Variable para los datos sobrecargados. */
|
|
private $data = array();
|
|
|
|
/** La sobrecarga no es utilizada en las propiedades declaradas. */
|
|
public $declared = 1;
|
|
|
|
/** La sobrecarga solo es lanzada cuando se accede a esta propiedad desde fuera de la clase. */
|
|
private $hidden = 2;
|
|
|
|
public function __set($name, $value)
|
|
{
|
|
echo "Definición de '$name' al valor '$value'\n";
|
|
$this->data[$name] = $value;
|
|
}
|
|
|
|
public function __get($name)
|
|
{
|
|
echo "Recuperación de '$name'\n";
|
|
if (array_key_exists($name, $this->data)) {
|
|
return $this->data[$name];
|
|
}
|
|
|
|
$trace = debug_backtrace();
|
|
trigger_error(
|
|
'Propiedad no definida vía __get() : ' . $name .
|
|
' en ' . $trace[0]['file'] .
|
|
' en la línea ' . $trace[0]['line'],
|
|
E_USER_NOTICE);
|
|
return null;
|
|
}
|
|
|
|
public function __isset($name)
|
|
{
|
|
echo "¿Está '$name' definido?\n";
|
|
return isset($this->data[$name]);
|
|
}
|
|
|
|
public function __unset($name)
|
|
{
|
|
echo "Borrado de '$name'\n";
|
|
unset($this->data[$name]);
|
|
}
|
|
|
|
/** Este no es un método mágico, necesario aquí solo para el ejemplo. */
|
|
public function getHidden()
|
|
{
|
|
return $this->hidden;
|
|
}
|
|
}
|
|
|
|
$obj = new PropertyTest;
|
|
|
|
$obj->a = 1;
|
|
echo $obj->a . "\n\n";
|
|
|
|
var_dump(isset($obj->a));
|
|
unset($obj->a);
|
|
var_dump(isset($obj->a));
|
|
echo "\n";
|
|
|
|
echo $obj->declared . "\n\n";
|
|
|
|
echo "Manipulemos ahora la propiedad privada llamada 'hidden' :\n";
|
|
echo "'hidden' es visible desde la clase, por lo que __get() no es utilizado...\n";
|
|
echo $obj->getHidden() . "\n";
|
|
echo "'hidden' no es visible fuera de la clase, por lo que __get() es utilizado...\n";
|
|
echo $obj->hidden . "\n";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen role="php">
|
|
<![CDATA[
|
|
Definición de 'a' a '1'
|
|
Recuperación de 'a'
|
|
1
|
|
|
|
¿Está 'a' definido?
|
|
bool(true)
|
|
Borrado de 'a'
|
|
¿Está 'a' definido?
|
|
bool(false)
|
|
|
|
1
|
|
|
|
Manipulemos ahora la propiedad privada llamada 'hidden' :
|
|
'hidden' es visible desde la clase, por lo que __get() no es utilizado...
|
|
2
|
|
'hidden' no es visible fuera de la clase, por lo que __get() es utilizado...
|
|
Recuperación de 'hidden'
|
|
|
|
|
|
Notice: Propiedad no definida vía __get() : hidden en <file> en la línea 64 en <file> en la línea 28
|
|
]]>
|
|
</screen>
|
|
|
|
</example>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="language.oop5.overloading.methods">
|
|
<title>Sobrecarga de métodos</title>
|
|
|
|
<methodsynopsis xml:id="object.call">
|
|
<modifier>public</modifier> <type>mixed</type><methodname>__call</methodname>
|
|
<methodparam><type>string</type><parameter>name</parameter></methodparam>
|
|
<methodparam><type>array</type><parameter>arguments</parameter></methodparam>
|
|
</methodsynopsis>
|
|
<methodsynopsis xml:id="object.callstatic">
|
|
<modifier>public static</modifier> <type>mixed</type><methodname>__callStatic</methodname>
|
|
<methodparam><type>string</type><parameter>name</parameter></methodparam>
|
|
<methodparam><type>array</type><parameter>arguments</parameter></methodparam>
|
|
</methodsynopsis>
|
|
|
|
<para>
|
|
<link linkend="object.call">__call()</link> es llamada cuando se invoca
|
|
métodos inaccesibles en un contexto de objeto.
|
|
</para>
|
|
|
|
<para>
|
|
<link linkend="object.callstatic">__callStatic()</link> es lanzada cuando se invoca
|
|
métodos inaccesibles en un contexto estático.
|
|
</para>
|
|
|
|
<para>
|
|
El argumento <varname>$name</varname> es el nombre del método llamado.
|
|
El argumento <varname>$arguments</varname> es un array que contiene
|
|
los parámetros pasados al método <varname>$name</varname>.
|
|
</para>
|
|
|
|
<example>
|
|
<title>Sobrecarga de métodos con
|
|
<link linkend="object.call">__call()</link> y
|
|
<link linkend="object.callstatic">__callStatic()</link></title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class MethodTest
|
|
{
|
|
public function __call($name, $arguments)
|
|
{
|
|
// Nota: el valor de $name es sensible a mayúsculas y minúsculas.
|
|
echo "Llamada al método '$name' "
|
|
. implode(', ', $arguments). "\n";
|
|
}
|
|
|
|
public static function __callStatic($name, $arguments)
|
|
{
|
|
// Nota: el valor de $name es sensible a mayúsculas y minúsculas.
|
|
echo "Llamada al método estático '$name' "
|
|
. implode(', ', $arguments). "\n";
|
|
}
|
|
}
|
|
|
|
$obj = new MethodTest;
|
|
$obj->runTest('en un contexto de objeto');
|
|
|
|
MethodTest::runTest('en un contexto static');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen role="php">
|
|
<![CDATA[
|
|
Llamada al método 'runTest' en un contexto de objeto
|
|
Llamada al método estático 'runTest' en un contexto static
|
|
]]>
|
|
</screen>
|
|
</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
|
|
-->
|