mirror of
https://github.com/php/doc-es.git
synced 2026-03-25 07:52:21 +01:00
git-svn-id: https://svn.php.net/repository/phpdoc/es/trunk@338335 c90b9560-bf6c-de11-be94-00142212c4b1
1573 lines
41 KiB
XML
1573 lines
41 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: 20f201c32ce940b21678860ebe00aad67c0cac96 Maintainer: seros Status: ready -->
|
|
<!-- Reviewed: no Maintainer: seros -->
|
|
<chapter xml:id="language.functions" xmlns="http://docbook.org/ns/docbook">
|
|
<title>Funciones</title>
|
|
|
|
<sect1 xml:id="functions.user-defined">
|
|
<title>Funciones definidas por el usuario</title>
|
|
|
|
<para>
|
|
Una función puede ser definida empleando una sintaxis como la siguiente:
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Seudocódigo para demostrar el uso de funciones</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
|
|
{
|
|
echo "Función de ejemplo.\n";
|
|
return $valor_devuelto;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<simpara>
|
|
Cualquier código PHP válido puede aparecer dentro de una función, incluso otras
|
|
funciones y definiciones de
|
|
<link linkend="keyword.class">clases</link>.
|
|
</simpara>
|
|
<para>
|
|
Los nombres de las funciones siguen las mismas reglas que las demás etiquetas de PHP. Un
|
|
nombre de función válido comienza con una letra o guión bajo, seguido de
|
|
cualquier número de letras, números o guiones bajos. Como expresión regular
|
|
se expresaría así:
|
|
<literal>[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*</literal>.
|
|
</para>
|
|
&tip.userlandnaming;
|
|
<simpara>
|
|
No es necesario definir una función antes de que sea referenciada,
|
|
<emphasis>excepto</emphasis> cuando esta esté condicionalmente definida como
|
|
se muestra en los dos ejemplos de abajo.
|
|
</simpara>
|
|
<para>
|
|
Cuando una función está definida de una forma condicional como en los dos
|
|
ejemplos siguientes, sus definiciones deben ser procesadas <emphasis>antes</emphasis>
|
|
de ser llamadas.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Funciones condicionales</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$hacer_algo = true;
|
|
|
|
/* No podemos llamar a foo() desde aquí
|
|
ya que no existe aún,
|
|
pero podemos llamar a bar() */
|
|
|
|
bar();
|
|
|
|
if ($hacer_algo) {
|
|
function foo()
|
|
{
|
|
echo "No existo hasta que la ejecución del programa llegue hasta mí.\n";
|
|
}
|
|
}
|
|
|
|
/* Ahora podemos llamar de forma segura a foo()
|
|
ya que $hacer_algo se evaluó como verdadero */
|
|
|
|
if ($hacer_algo) foo();
|
|
|
|
function bar()
|
|
{
|
|
echo "Existo desde el momento inmediato que comenzó el programa.\n";
|
|
}
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Funciones dentro de funciones</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function foo()
|
|
{
|
|
function bar()
|
|
{
|
|
echo "No existo hasta que se llame a foo().\n";
|
|
}
|
|
}
|
|
|
|
/* No podemos llamar aún a bar()
|
|
ya que no existe. */
|
|
|
|
foo();
|
|
|
|
/* Ahora podemos llamar a bar(),
|
|
el procesamiento de foo()
|
|
la ha hecho accesible. */
|
|
|
|
bar();
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Todas las funciones y clases de PHP tienen ámbito global. Se pueden
|
|
llamar desde fuera de una función incluso si fueron definidas dentro, y viceversa.
|
|
</para>
|
|
<simpara>
|
|
PHP no admite la sobrecarga de funciones, ni es posible
|
|
'desdefinir' ni redefinir funciones previamente declaradas.
|
|
</simpara>
|
|
<note>
|
|
<simpara>
|
|
Los nombres de las fuciones son insensibles a mayúsculas-minúsculas, aunque es una buena
|
|
idea llamar a las funciones tal y como aparecen en sus declaraciones.
|
|
</simpara>
|
|
</note>
|
|
<simpara>
|
|
Las funciones admiten un <link linkend="functions.variable-arg-list">número variable de
|
|
argumentos</link> y <link linkend="functions.arguments.default">argumentos
|
|
predeterminados</link>. Véanse también las referencias
|
|
de funciones para
|
|
<function>func_num_args</function>,
|
|
<function>func_get_arg</function>, y
|
|
<function>func_get_args</function> para más información.
|
|
</simpara>
|
|
|
|
<para>
|
|
En PHP es posible llamar a funciones recursivas.
|
|
<example>
|
|
<title>Funciones recursivas</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function recursividad($a)
|
|
{
|
|
if ($a < 20) {
|
|
echo "$a\n";
|
|
recursividad($a + 1);
|
|
}
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
<note>
|
|
<simpara>
|
|
Las llamadas a funciones/métodos recursivos con más de 100-200 niveles de recursividad pueden
|
|
agotar la pila y ocasionar la finalización del script en curso. Especialmente,
|
|
las recurisvidades infinitas están consideradas un error de programación.
|
|
</simpara>
|
|
</note>
|
|
</para>
|
|
|
|
</sect1>
|
|
|
|
<sect1 xml:id="functions.arguments">
|
|
<title>Argumentos de funciones</title>
|
|
|
|
<simpara>
|
|
Cualquier información puede ser pasada a las funciones mediante la lista de argumentos,
|
|
la cual es una lista de expresiones delimitadas por comas. Los argumentos son
|
|
evaluados de izquierda a derecha.
|
|
</simpara>
|
|
|
|
<para>
|
|
PHP admite el paso de argumentos por valor (lo predeterminado), <link
|
|
linkend="functions.arguments.by-reference">el paso por
|
|
referencia</link>, y <link
|
|
linkend="functions.arguments.default">valores de argumentos
|
|
predeterminados</link>. Las <link linkend="functions.variable-arg-list">Listas de argumentos
|
|
de longitud variable</link> también están soportadas.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Pasar arrays a funciones</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function tomar_array($entrada)
|
|
{
|
|
echo "$entrada[0] + $entrada[1] = ".$entrada[0]+$entrada[1];
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<sect2 xml:id="functions.arguments.by-reference">
|
|
<title>Paso de argumentos por referencia</title>
|
|
|
|
<simpara>
|
|
Por defecto, los argumentos de las funciones son pasados por valor (así, si
|
|
el valor del argumento dentro de la función cambia, este no
|
|
cambia fuera de la función). Para permitir a una función modificar sus
|
|
argumentos, éstos deben pasarse por referencia.
|
|
</simpara>
|
|
<para>
|
|
Para hacer que un argumento a una función sea siempre pasado por referencia hay que anteponer
|
|
al nombre del argumento el signo 'et' (&) en la definición de la función:
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Paso de parámetros de una función por referencia</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function añadir_algo(&$cadena)
|
|
{
|
|
$cadena .= 'y algo más.';
|
|
}
|
|
$cad = 'Esto es una cadena, ';
|
|
añadir_algo($cad);
|
|
echo $cad; // imprime 'Esto es una cadena, y algo más.'
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</sect2>
|
|
<sect2 xml:id="functions.arguments.default">
|
|
<title>Valores de argumentos predeterminados</title>
|
|
|
|
<para>
|
|
Una función puede definir valores predeterminados al estilo de C++ para argumentos
|
|
escalares como sigue:
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Uso de parámetros predeterminados en funciones</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function hacer_café($tipo = "capuchino")
|
|
{
|
|
return "Hacer una taza de $tipo.\n";
|
|
}
|
|
echo hacer_café();
|
|
echo hacer_café(null);
|
|
echo hacer_café("espresso");
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
Hacer una taza de capuchino.
|
|
Hacer una taza de .
|
|
Hacer una taza de espresso.
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
PHP también permite el uso de <type>array</type>s y del tipo especial &null;
|
|
como valores predeterminados, por ejemplo:
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Usar tipos no escalares como valores predeterminados</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function hacer_café($tipos = array("capuchino"), $fabricanteCafé = NULL)
|
|
{
|
|
$aparato = is_null($fabricanteCafé) ? "las manos" : $fabricanteCafé;
|
|
return "Hacer una taza de ".join(", ", $tipos)." con $aparato.\n";
|
|
}
|
|
echo hacer_café();
|
|
echo hacer_café(array("capuchino", "lavazza"), "una tetera");
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
|
|
</para>
|
|
<simpara>
|
|
El valor predeterminado debe ser una expresión constante, no (por
|
|
ejemplo) una variable, un miembro de una clase o una llamada a una función.
|
|
</simpara>
|
|
<para>
|
|
Obsérvese que cuando se emplean argumentos predeterminados, cualquiera de ellos debería estar a
|
|
la derecha de los argumentos no predeterminados; si no, las cosas
|
|
no funcionarán como se esperaba. Considérese el siguiente trozo de código:
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Uso incorrecto de argumentos predeterminados en una función</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function hacer_yogur($tipo = "acidófilo", $sabor)
|
|
{
|
|
return "Hacer un tazón de yogur $tipo de $sabor.\n";
|
|
}
|
|
|
|
echo hacer_yogur("frambuesa"); // no funcionará como se esperaba
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
Warning: Missing argument 2 in call to hacer_yogur() in
|
|
/usr/local/etc/httpd/htdocs/phptest/functest.html on line 41
|
|
Hacer un tazón de yogur frambuesa de .
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Ahora, compare el ejemplo de arriba con este:
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Uso correcto de argumentos predeterminados en una función</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function hacer_yogur($sabor, $tipo = "acidófilo")
|
|
{
|
|
return "Hacer un tazón de yogur $tipo de $sabor.\n";
|
|
}
|
|
|
|
echo hacer_yogur("frambuesa"); // funciona como se esperaba
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
Hacer un tazón de yogur acidófilo de frambuensa.
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
A partir de PHP 5, los argumentos pasados por referencia pueden tener un valor predeterminado.
|
|
</simpara>
|
|
</note>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="functions.arguments.type-declaration">
|
|
<title>Declaraciones de tipo</title>
|
|
|
|
<note>
|
|
<para>
|
|
La declaración de tipos también se conoce como 'Determinación de tipos' en PHP 5.
|
|
</para>
|
|
</note>
|
|
|
|
<para>
|
|
Las declaraciones de tipo permiten a las funciones especificar que los parámetros sean de cierto tipo.
|
|
Si el valor dado es de un tipo incorrecto,
|
|
se generará un error: en PHP 5, este error es un error fatal
|
|
recuperable, mientras que PHP 7 lanzará una excepción
|
|
<classname>TypeError</classname>.
|
|
</para>
|
|
|
|
<para>
|
|
Para especificar una declaración de tipo, debe anteponerse el nombre del tipo al
|
|
nombre del parámetro. Se puede hacer que una declaración acepte valores &null; si
|
|
el valor predeterminado del parámetro se establece a &null;.
|
|
</para>
|
|
|
|
<sect3 xml:id="functions.arguments.type-declaration.types">
|
|
<title>Tipos válidos</title>
|
|
<informaltable>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Tipo</entry>
|
|
<entry>Descripción</entry>
|
|
<entry>Versión de PHP mínima</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>nombre de clase/interfaz</entry>
|
|
<entry>
|
|
El parámetro debe ser una &instanceof; del nombre de la clase o interfaz
|
|
dada.
|
|
</entry>
|
|
<entry>PHP 5.0.0</entry>
|
|
</row>
|
|
<row>
|
|
<entry><literal>self</literal></entry>
|
|
<entry>
|
|
El parámetro debe ser una &instanceof; de la misma clase donde
|
|
está definido el método. Esto solamente se puede utilizar en clases
|
|
y métodos de instancia.
|
|
</entry>
|
|
<entry>PHP 5.0.0</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>array</type></entry>
|
|
<entry>
|
|
El parámetro debe ser un <type>array</type>.
|
|
</entry>
|
|
<entry>PHP 5.1.0</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>callable</type></entry>
|
|
<entry>
|
|
El parámetro debe ser un <type>callable</type> válido.
|
|
</entry>
|
|
<entry>PHP 5.4.0</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>bool</type></entry>
|
|
<entry>
|
|
El parámetro debe ser un valor de tipo <type>boolean</type>.
|
|
</entry>
|
|
<entry>PHP 7.0.0</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>float</type></entry>
|
|
<entry>
|
|
El parámetro debe ser un número de tipo <type>float</type>.
|
|
</entry>
|
|
<entry>PHP 7.0.0</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>int</type></entry>
|
|
<entry>
|
|
El parámetro debe ser un valor de tipo <type>integer</type>.
|
|
</entry>
|
|
<entry>PHP 7.0.0</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>string</type></entry>
|
|
<entry>
|
|
El parámetro debe ser un <type>string</type>.
|
|
</entry>
|
|
<entry>PHP 7.0.0</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<warning>
|
|
<para>
|
|
Los alias de los tipos escalares anteriores no están admitidos. En su lugar, son
|
|
tratados como nombres de clases o de interfaces. Por ejemplo, el empleo de
|
|
<literal>boolean</literal> como parámetro o como tipo devuelto requerirá
|
|
un argumento o un valor devuelto que sea unaan &instanceof; de la clase o
|
|
interfaz <literal>boolean</literal>, más que el tipo
|
|
<type>bool</type>:
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function prueba(boolean $param) {}
|
|
prueba(true);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of boolean, boolean given, called in - on line 1 and defined in -:1
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
</warning>
|
|
</sect3>
|
|
|
|
<sect3 xml:id="functions.arguments.type-declaration.examples">
|
|
&reftitle.examples;
|
|
<example>
|
|
<title>Declaración básica de tipo clase</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class C {}
|
|
class D extends C {}
|
|
|
|
// Esta no extiende a C.
|
|
class E {}
|
|
|
|
function f(C $c) {
|
|
echo get_class($c)."\n";
|
|
}
|
|
|
|
f(new C);
|
|
f(new D);
|
|
f(new E);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
C
|
|
D
|
|
|
|
Fatal error: Uncaught TypeError: Argument 1 passed to f() must be an instance of C, instance of E given, called in - on line 14 and defined in -:8
|
|
Stack trace:
|
|
#0 -(14): f(Object(E))
|
|
#1 {main}
|
|
thrown in - on line 8
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Declaración básica de tipo interfaz</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
interface I { public function f(); }
|
|
class C implements I { public function f() {} }
|
|
|
|
// Esta no implementa I.
|
|
class E {}
|
|
|
|
function f(I $i) {
|
|
echo get_class($i)."\n";
|
|
}
|
|
|
|
f(new C);
|
|
f(new E);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
C
|
|
|
|
Fatal error: Uncaught TypeError: Argument 1 passed to f() must implement interface I, instance of E given, called in - on line 13 and defined in -:8
|
|
Stack trace:
|
|
#0 -(13): f(Object(E))
|
|
#1 {main}
|
|
thrown in - on line 8
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Declaración de tipo null</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class C {}
|
|
|
|
function f(C $c = null) {
|
|
var_dump($c);
|
|
}
|
|
|
|
f(new C);
|
|
f(null);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
object(C)#1 (0) {
|
|
}
|
|
NULL
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</sect3>
|
|
|
|
<sect3 xml:id="functions.arguments.type-declaration.strict">
|
|
<title>Tipificación estricta</title>
|
|
|
|
<para>
|
|
Por defecto, PHP fuerza a los valores de un tipo erróneo a ser del tipo
|
|
escalar esperado si es posible. Por ejemplo, una función a la que se le pasa un
|
|
<type>integer</type> para un parámetro que se prevé sea un <type>string</type>
|
|
obtendrá una variable de tipo <type>string</type>.
|
|
</para>
|
|
|
|
<para>
|
|
Es posible habilitar el modo escricto en función de cada fichero. El el modo
|
|
estricto solamente será aceptada una variable del tipo exacto de la declaración
|
|
de tipo, o será lanzada una <classname>TypeError</classname>. La
|
|
única excepción a esta regla es que se podría proporcionar un <type>integer</type>
|
|
a una función que espere un <type>float</type>.
|
|
</para>
|
|
|
|
<para>
|
|
Para habilitar el modo escricto se emplea la sentencia &declare; con la
|
|
declaración <literal>strict_types</literal>:
|
|
</para>
|
|
|
|
<caution>
|
|
<para>
|
|
Habilitar el modo esctricto también afectará a las
|
|
<link linkend="functions.returning-values.type-declaration">declaraciones de tipo de devolución</link>.
|
|
</para>
|
|
</caution>
|
|
|
|
<note>
|
|
<para>
|
|
La tipificación estricta se aplica a las llamadas a funciones hechas desde
|
|
<emphasis>dentro</emphasis> del fichero con la tipificación estricta habilitada, no a
|
|
las funciones declaradas dentro del fichero. Si un fichero sin la tipificación estricta
|
|
habilitada realiza una llamada a una función definida en un fichero
|
|
con tipificación estricta, será respetada la preferencia del llamador
|
|
(tipificación débil), y se forzará el valor.
|
|
</para>
|
|
</note>
|
|
|
|
<note>
|
|
<para>
|
|
La tipificación estricta solamente se define para declaraciones de tipos escalares, y como
|
|
tal, requiere PHP 7.0.0 o posterior, ya que las declaraciones de tipo escalar fueron
|
|
añadidas en esta versión.
|
|
</para>
|
|
</note>
|
|
|
|
<example>
|
|
<title>Tipificación estricta</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
declare(strict_types=1);
|
|
|
|
function sum(int $a, int $b) {
|
|
return $a + $b;
|
|
}
|
|
|
|
var_dump(sum(1, 2));
|
|
var_dump(sum(1.5, 2.5));
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
int(3)
|
|
|
|
Fatal error: Uncaught TypeError: Argument 1 passed to sum() must be of the type integer, float given, called in - on line 9 and defined in -:4
|
|
Stack trace:
|
|
#0 -(9): sum(1.5, 2.5)
|
|
#1 {main}
|
|
thrown in - on line 4
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Tipificación débil</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function sum(int $a, int $b) {
|
|
return $a + $b;
|
|
}
|
|
|
|
var_dump(sum(1, 2));
|
|
|
|
// Estos números serán forzados a ser enteros: ¡observe la salida de abajo!
|
|
var_dump(sum(1.5, 2.5));
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
int(3)
|
|
int(3)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Capturar la excepción <classname>TypeError</classname></title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
declare(strict_types=1);
|
|
|
|
function sum(int $a, int $b) {
|
|
return $a + $b;
|
|
}
|
|
|
|
try {
|
|
var_dump(sum(1, 2));
|
|
var_dump(sum(1.5, 2.5));
|
|
} catch (TypeError $e) {
|
|
echo 'Error: '.$e->getMessage();
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
int(3)
|
|
Error: Argument 1 passed to sum() must be of the type integer, float given, called in - on line 10
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</sect3>
|
|
</sect2>
|
|
<sect2 xml:id="functions.variable-arg-list">
|
|
<title>Listas de argumentos de longitud variable</title>
|
|
|
|
<simpara>
|
|
PHP tiene soporte para listas de argumentos de longitud variable en
|
|
funciones definidas por el usuario. Esto se implementa utilizando el
|
|
token <literal>...</literal> en PHP 5.6 y posteriores, y utilizando las funciones
|
|
<function>func_num_args</function>,
|
|
<function>func_get_arg</function>, y
|
|
<function>func_get_args</function> en PHP 5.5 y anteriores.
|
|
</simpara>
|
|
|
|
<sect3 xml:id="functions.variable-arg-list.new">
|
|
<title><literal>...</literal> en PHP 5.6+</title>
|
|
|
|
<para>
|
|
En PHP 5.6 y posteriores, las listas de argumentos pueden incluir el
|
|
token <literal>...</literal> para denotar que la función acepta un
|
|
número variable de argumentos. Los argumentos serán pasados a la
|
|
variable dada como un aryay, por ejemplo:
|
|
|
|
<example>
|
|
<title>Usando <literal>...</literal> para acceder a argumentos variables</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function sum(...$números) {
|
|
$acc = 0;
|
|
foreach ($números as $n) {
|
|
$acc += $n;
|
|
}
|
|
return $acc;
|
|
}
|
|
|
|
echo sum(1, 2, 3, 4);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
10
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
También se puede emplear <literal>...</literal> al llamar a funciones para convertir
|
|
un <type>array</type> o variable <classname>Traversable</classname> o
|
|
literal en una lista de argumentos:
|
|
|
|
<example>
|
|
<title>Usar <literal>...</literal> para proporcionar argumentos</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function add($a, $b) {
|
|
return $a + $b;
|
|
}
|
|
|
|
echo add(...[1, 2])."\n";
|
|
|
|
$a = [1, 2];
|
|
echo add(...$a);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
3
|
|
3
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
Se puede especifcar argumentos posicionales normales antes del
|
|
token <literal>...</literal>. En este caso, solamente los argumentos al final
|
|
que no coincidan con un argumento posicional serán añadidos al array
|
|
generado por <literal>...</literal>.
|
|
</para>
|
|
|
|
<para>
|
|
También es posible añadir una
|
|
<link linkend="language.oop5.typehinting">declraración de tipo</link> antes del
|
|
símbolo <literal>...</literal>. Si está presente, todos los argumentos
|
|
capturados por <literal>...</literal> deben ser objetos de la clase implicada.
|
|
|
|
<example>
|
|
<title>Argumentos variables de declaración de tipo</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function total_intervals($unit, DateInterval ...$intervals) {
|
|
$time = 0;
|
|
foreach ($intervals as $interval) {
|
|
$time += $interval->$unit;
|
|
}
|
|
return $time;
|
|
}
|
|
|
|
$a = new DateInterval('P1D');
|
|
$b = new DateInterval('P2D');
|
|
echo total_intervals('d', $a, $b).' days';
|
|
|
|
// Esto fallará, debido a que null no es un objeto de DateInterval.
|
|
echo total_intervals('d', null);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
3 days
|
|
Catchable fatal error: Argument 2 passed to total_intervals() must be an instance of DateInterval, null given, called in - on line 14 and defined in - on line 2
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
Por último, también es pueden pasar argumentos variables
|
|
<link linkend="functions.arguments.by-reference">por referencia</link>
|
|
prefijando <literal>...</literal> con el signo
|
|
(<literal>&</literal>).
|
|
</para>
|
|
</sect3>
|
|
|
|
<sect3 xml:id="functions.variable-arg-list.old">
|
|
<title>Versiones antiguas de PHP</title>
|
|
|
|
<para>
|
|
No se requiere una sintaxis especial para señalar que una función es varíadica;
|
|
sin embargo, para acceder a los argumentos de la función se debe usar
|
|
<function>func_num_args</function>, <function>func_get_arg</function>
|
|
y <function>func_get_args</function>.
|
|
</para>
|
|
|
|
<para>
|
|
El primer ejemplo de antes se implementaría en PHP 5.5 y anteriores
|
|
como sigue:
|
|
|
|
<example>
|
|
<title>Acceder a argumentos variables en PHP 5.5 y anteriores</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function sum() {
|
|
$acc = 0;
|
|
foreach (func_get_args() as $n) {
|
|
$acc += $n;
|
|
}
|
|
return $acc;
|
|
}
|
|
|
|
echo sum(1, 2, 3, 4);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
10
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
</sect3>
|
|
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="functions.returning-values">
|
|
<title>Devolver valores</title>
|
|
|
|
<para>
|
|
Los valores son devueltos usando la sentencia opcional return. Se
|
|
puede devolver cualquier tipo, incluidos arrays y objetos. Esto causa que la
|
|
función finalice su ejecución inmediatamente y pase el control de nuevo a
|
|
la línea desde la que fue llamada. Véase <function>return</function>
|
|
para más información.
|
|
</para>
|
|
|
|
<note>
|
|
<para>
|
|
Si se omite <function>return</function>, el valor devuelto será
|
|
&null;.
|
|
</para>
|
|
</note>
|
|
|
|
<sect2>
|
|
<title>Empleo de return</title>
|
|
<para>
|
|
<example>
|
|
<title>Empleo de <function>return</function></title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function cuadrado($núm)
|
|
{
|
|
return $núm * $núm;
|
|
}
|
|
echo cuadrado(4); // imprime '16'.
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
Una función no puede devolver múltiples valores, pero se pueden obtener resultados
|
|
similares devolviendo un array.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Devolver un array para obtener múltiples valores</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function números_pequeños()
|
|
{
|
|
return array (0, 1, 2);
|
|
}
|
|
list ($cero, $uno, $dos) = números_pequeños();
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Para devolver una referencia desde una función use el operador de referencia &, en
|
|
la declaración de la función y cuando se asigne el valor devuelto a una
|
|
variable:
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Devolver una referencia desde una función</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function &devolver_referencia()
|
|
{
|
|
return $algunaref;
|
|
}
|
|
|
|
$nuevaref =& devolver_referencia();
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<simpara>
|
|
Para más información sobre referencias, por favor, lea las <link
|
|
linkend="language.references">Referencias explicadas</link>.
|
|
</simpara>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="functions.returning-values.type-declaration">
|
|
<title>Declaraciones de tipo de devolución</title>
|
|
|
|
<para>
|
|
PHP 7 añade soporte para las declaraciones de tipo de devolución. De forma similar a las
|
|
<link linkend="functions.arguments.type-declaration">declaraciones de tipo de argumento</link>,
|
|
las declaraciones de tipo de devolución especifican el tipo del valor que serán
|
|
devuelto desde una función. Están disponibles los mismos
|
|
<link linkend="functions.arguments.type-declaration.types">tipos</link>
|
|
para las declaraciones de tipo de devolución que para las declaraciones
|
|
de tipo de argumento.
|
|
</para>
|
|
|
|
<para>
|
|
La <link linkend="functions.arguments.type-declaration.strict">tipificación estricta</link>
|
|
también tiene efecto sobre las declaraciones de tipo de devolución. En el modo predeterminado de tipificacón débil,
|
|
los valores devueltos serán forzados al tipo correcto si no son ya
|
|
de ese tipo. En el modo fuerte, el valor devuelto debe ser del
|
|
tipo correcto, o de lo contrario se lanzará una excepción <classname>TypeError</classname>.
|
|
</para>
|
|
|
|
<note>
|
|
<para>
|
|
Al sobrescribir un método padre, el método hijo debe hacer coincidir cualquier
|
|
declaración de tipo de devolución del padre. Si el padre no define un tipo de
|
|
devolución, el método hijo puede hacerlo.
|
|
</para>
|
|
</note>
|
|
|
|
<sect3 xml:id="functions.returning-values.type-declaration.examples">
|
|
&reftitle.examples;
|
|
|
|
<example>
|
|
<title>Declaración básica de tipo de devolución</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function sum($a, $b): float {
|
|
return $a + $b;
|
|
}
|
|
|
|
// Observe que será devuelto un float.
|
|
var_dump(sum(1, 2));
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
float(3)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
|
|
<example>
|
|
<title>El modo estricto en acción</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
declare(strict_types=1);
|
|
|
|
function sum($a, $b): int {
|
|
return $a + $b;
|
|
}
|
|
|
|
var_dump(sum(1, 2));
|
|
var_dump(sum(1, 2.5));
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
int(3)
|
|
|
|
Fatal error: Uncaught TypeError: Return value of sum() must be of the type integer, float returned in - on line 5 in -:5
|
|
Stack trace:
|
|
#0 -(9): sum(1, 2.5)
|
|
#1 {main}
|
|
thrown in - on line 5
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Devolver un objeto</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class C {}
|
|
|
|
function getC(): C {
|
|
return new C;
|
|
}
|
|
|
|
var_dump(getC());
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
object(C)#1 (0) {
|
|
}
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</sect3>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="functions.variable-functions">
|
|
<title>Funciones variables</title>
|
|
|
|
<para>
|
|
PHP admite el concepto de funciones variables. Esto significa que si
|
|
un nombre de variable tiene paréntesis anexos a él, PHP buscará
|
|
una función con el mismo nombre que lo evaluado por la variable,
|
|
e intentará ejecutarla. Entre otras cosas, esto se puede
|
|
usar para implementar llamadas de retorno, tablas de funciones, y así sucesivamente.
|
|
</para>
|
|
<para>
|
|
Las funciones variables no funcionarán con constructores de lenguaje como
|
|
<function>echo</function>, <function>print</function>,
|
|
<function>unset</function>, <function>isset</function>,
|
|
<function>empty</function>, <function>include</function>,
|
|
<function>require</function> y similares. Utilice funciones de envoltura para hacer
|
|
uso de cualquiera de estos constructores como funciones variables.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Ejemplo de función variable</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function foo() {
|
|
echo "En foo()<br />\n";
|
|
}
|
|
|
|
function bar($arg = '')
|
|
{
|
|
echo "En bar(); el argumento era '$arg'.<br />\n";
|
|
}
|
|
|
|
// Esta es una función de envoltura alrededor de echo
|
|
function hacerecho($cadena)
|
|
{
|
|
echo $cadena;
|
|
}
|
|
|
|
$func = 'foo';
|
|
$func(); // Esto llama a foo()
|
|
|
|
$func = 'bar';
|
|
$func('prueba'); // Esto llama a bar()
|
|
|
|
$func = 'hacerecho';
|
|
$func('prueba'); // Esto llama a hacerecho()
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Los métodos de objetos también puede ser llamados con la sintaxis de funciones variables.
|
|
<example>
|
|
<title>Ejemplo de método variable</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class Foo
|
|
{
|
|
function Variable()
|
|
{
|
|
$nombre = 'Bar';
|
|
$this->$nombre(); // Esto llama al método Bar()
|
|
}
|
|
|
|
function Bar()
|
|
{
|
|
echo "Esto es Bar";
|
|
}
|
|
}
|
|
|
|
$foo = new Foo();
|
|
$nombrefunc = "Variable";
|
|
$foo->$nombrefunc(); // Esto llama a $foo->Variable()
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Cuando se llaman a métodos estáticos, la llamada a la función es más fuerte que el operador de
|
|
propiedad static:
|
|
<example>
|
|
<title>Ejemplo de método variable con propiedades estáticas</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class Foo
|
|
{
|
|
static $variable = 'propiedad estática';
|
|
static function Variable()
|
|
{
|
|
echo 'Método Variable llamado';
|
|
}
|
|
}
|
|
|
|
echo Foo::$variable; // Esto imprime 'propiedad estática'. No necesita una $variable en este ámbito.
|
|
$variable = "Variable";
|
|
Foo::$variable(); // Esto llama a $foo->Variable() leyendo $variable en este ámbito.
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
A partir de PHP 5.4.0, se puede llamar a cualquier <type>callable</type> almacenado en una variable.
|
|
<example>
|
|
<title>Llamables complejos</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
class Foo
|
|
{
|
|
static function bar()
|
|
{
|
|
echo "bar\n";
|
|
}
|
|
function baz()
|
|
{
|
|
echo "baz\n";
|
|
}
|
|
}
|
|
|
|
$func = array("Foo", "bar");
|
|
$func(); // imprime "bar"
|
|
$f = array(new Foo, "baz");
|
|
$func(); // imprime "baz"
|
|
$f = "Foo::bar";
|
|
$func(); // imprime "bar" a partrid de PHP 7.0.0; antes, emitía un error fatal
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
Véase también <function>is_callable</function>, <function>call_user_func</function>,
|
|
<link linkend="language.variables.variable">
|
|
variables variables</link> y <function>function_exists</function>.
|
|
</para>
|
|
|
|
<sect2 role="changelog">
|
|
&reftitle.changelog;
|
|
<para>
|
|
<informaltable>
|
|
<tgroup cols="2">
|
|
<thead>
|
|
<row>
|
|
<entry>&Version;</entry>
|
|
<entry>&Description;</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>7.0.0</entry>
|
|
<entry>
|
|
'NombreDeClase::NombreDeMétodo' se permite como función variable.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>5.4.0</entry>
|
|
<entry>
|
|
Los arrays, que son llamables válidos, están permitidos como funciones variables.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="functions.internal">
|
|
<title>Funciones internas (incluidas)</title>
|
|
|
|
<para>
|
|
PHP se estandariza con muchas funciones y construcciones. También existen
|
|
funciones que necesitan extensiones específicas de PHP compiladas, si no,
|
|
aparecerán errores fatales "undefined function" ("función no definida"). Por ejemplo,
|
|
para usar las funciones de <link linkend="ref.image">image</link> tales como
|
|
<function>imagecreatetruecolor</function>, PHP debe ser compilado con
|
|
soporte para <productname>GD</productname>. O para usar
|
|
<function>mysql_connect</function>, PHP debe ser compilado con
|
|
soporte para <link linkend="ref.mysql">MySQL</link>. Hay muchas funciones de núcleo
|
|
que está incluidas en cada versión de PHP, tales como las
|
|
funciones de <link linkend="ref.strings">string</link> y de
|
|
<link linkend="ref.var">variable</link>. Una llamada
|
|
a <function>phpinfo</function> o
|
|
<function>get_loaded_extensions</function> mostrará las extensiones que están
|
|
cargadas en PHP. Observe también que muchas extensiones están habilitadas por defecto y
|
|
que el manual de PHP está dividido por extensiones. Véase
|
|
<link linkend="configuration">configuración</link>,
|
|
<link linkend="install">instalación</link>, y capítulos individuales
|
|
de extensiones para más información sobre cómo configurar PHP.
|
|
</para>
|
|
<para>
|
|
Interpretar y comprender un prototipo de una función está explicado dentro de
|
|
la sección del manual titulada <link linkend="about.prototypes">cómo interpretar
|
|
la definición de una función</link>. Es importante comprender lo que devuelve una
|
|
función o si una función funciona directamente con un valor pasado. Por ejemplo,
|
|
<function>str_replace</function> devolverá la cadena modificada mientras que
|
|
<function>usort</function> funciona con la variable actual pasada.
|
|
Cada página del manual también tiene información específica para cada
|
|
función, como información sobre parámetros de funciones, cambios de comportamiento,
|
|
valores devueltos en caso de éxito o fallo, e información de disponibilidad.
|
|
Conocer estas importantes diferencias (a menudo imperceptibles) es crucial para
|
|
escribir código de PHP correcto.
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
Si los parámetros dados a una función no son los que se esperaban, como
|
|
pasar un <type>array</type> donde se esperaba un <type>string</type>,
|
|
el valor devuelto de la función será indefinido. En este caso lo más probable
|
|
es que devuelva &null; pero esto es sólo una convención, y no se puede confiar
|
|
en ello.
|
|
</simpara>
|
|
</note>
|
|
<para>
|
|
Véase también <function>function_exists</function>,
|
|
<link linkend="funcref">la referencia de funciones</link>,
|
|
<function>get_extension_funcs</function>, y
|
|
<function>dl</function>.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="functions.anonymous">
|
|
<title>Funciones anónimas</title>
|
|
|
|
<simpara>
|
|
Las funciones anónimas, también conocidas como <literal>clausuras</literal> (closures), permiten
|
|
la creación de funciones que no tienen un nombre especificado. Son más útiles como
|
|
valor de los parámetros de <link linkend="language.types.callback">llamadas de retorno</link>,
|
|
pero tienen muchos otros usos.
|
|
</simpara>
|
|
|
|
<example>
|
|
<title>Ejemplo de función anónima</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
echo preg_replace_callback('~-([a-z])~', function ($coincidencia) {
|
|
return strtoupper($coincidencia[1]);
|
|
}, 'hola-mundo');
|
|
// imprime holaMundo
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
|
|
<simpara>
|
|
Las clausuras también se pueden usar como valores de variables; PHP automáticamente
|
|
convierte tales expresiones en instancias de la
|
|
clase interna <classname>Closure</classname>. Se asume que una clausura a una
|
|
variable usa la misma sintaxis que cualquier otra asignación, incluido el
|
|
punto y coma final:
|
|
</simpara>
|
|
|
|
<example>
|
|
<title>Ejemplo de asignación de variable de una función anónima</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$saludo = function($nombre)
|
|
{
|
|
printf("Hola %s\r\n", $nombre);
|
|
};
|
|
|
|
$saludo('Mundo');
|
|
$saludo('PHP');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
|
|
<simpara>
|
|
Las clausuras también pueden heredar variables del ámbito padre. Cualquier
|
|
variable de estas debe ser pasado al constructor del lenguaje <literal>use</literal>.
|
|
</simpara>
|
|
|
|
<example>
|
|
<title>Heredar variables de un ámbito padre</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$mensaje = 'hola';
|
|
|
|
// Sin "use"
|
|
$ejemplo = function () {
|
|
var_dump($mensaje);
|
|
};
|
|
$ejemplo();
|
|
|
|
// Heredar $mensaje
|
|
$ejemplo = function () use ($mensaje) {
|
|
var_dump($mensaje);
|
|
};
|
|
$ejemplo();
|
|
|
|
// El valor de la variable heredada está cuando la función
|
|
// está definida, no cuando se le invoca
|
|
$mensaje = 'mundo';
|
|
$ejemplo();
|
|
|
|
// Reiniciar el mensaje
|
|
$mensaje = 'hola';
|
|
|
|
// Heredar por referencia
|
|
$ejemplo = function () use (&$mensaje) {
|
|
var_dump($mensaje);
|
|
};
|
|
$ejemplo();
|
|
|
|
// El valor cambiado en el ámbito padre
|
|
// se refleja dentro de la llamada a la función
|
|
$mensaje = 'mundo';
|
|
$ejemplo();
|
|
|
|
// Las clausuras también aceptan argumentos normales
|
|
$ejemplo = function ($arg) use ($mensaje) {
|
|
var_dump($arg . ' ' . $mensaje);
|
|
};
|
|
$ejemplo("hola");
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs.similar;
|
|
<screen>
|
|
<![CDATA[
|
|
Notice: Undefined variable: message in /example.php on line 6
|
|
NULL
|
|
string(4) "hola"
|
|
string(4) "hola"
|
|
string(4) "hola"
|
|
string(5) "mundo"
|
|
string(10) "hola mundo"
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
|
|
<simpara>
|
|
Heredar variables del ámbito padre <emphasis>no</emphasis>
|
|
es lo mismo que usar variables globales.
|
|
Las variables globales existen en el ámbito global, lo que implica que no
|
|
importa qué función se esté ejecutando. El ámbito padre de una clausura es la
|
|
función en la que la clausura fue declarado (no necesariamente la función
|
|
desde la que se llamó). Vea el siguiente ejemplo:
|
|
</simpara>
|
|
|
|
<example>
|
|
<title>Clausuras y ámbito</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// Un carro de compras básico que contiene una lista de productos añadidos
|
|
// y la cantidad de cada producto. Incluye un método que
|
|
// calcula el precio total de los artículos del carro usando una
|
|
// clausura como llamada de retorno.
|
|
class Carro
|
|
{
|
|
const PRECIO_MANTEQUILLA = 1.00;
|
|
const PRECIO_LECHE = 3.00;
|
|
const PRECIO_HUEVOS = 6.95;
|
|
|
|
protected $productos = array();
|
|
|
|
public function añadir($producto, $cantidad)
|
|
{
|
|
$this->productos[$producto] = $cantidad;
|
|
}
|
|
|
|
public function obtenerCantidad($producto)
|
|
{
|
|
return isset($this->productos[$producto]) ? $this->productos[$producto] :
|
|
FALSE;
|
|
}
|
|
|
|
public function obtenerTotal($impuesto)
|
|
{
|
|
$total = 0.00;
|
|
|
|
$llamadaDeRetorno =
|
|
function ($cantidad, $producto) use ($impuesto, &$total)
|
|
{
|
|
$precioUnidad = constant(__CLASS__ . "::PRECIO_" .
|
|
strtoupper($producto));
|
|
$total += ($precioUnidad * $cantidad) * ($impuesto + 1.0);
|
|
};
|
|
|
|
array_walk($this->productos, $llamadaDeRetorno);
|
|
return round($total, 2);
|
|
}
|
|
}
|
|
|
|
$mi_carro = new Carro;
|
|
|
|
// Añadir algunos artículos al carro
|
|
$mi_carro->añadir('mantequilla', 1);
|
|
$mi_carro->añadir('leche', 3);
|
|
$mi_carro->añadir('huevos', 6);
|
|
|
|
// Imprimir el total con un impuesto de venta del 5%.
|
|
print $mi_carro->obtenerTotal(0.05) . "\n";
|
|
// El resultado es 54.29
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
|
|
<simpara>
|
|
Las funciones anónimas son implementadas usando la clase <link linkend="class.closure">
|
|
<classname>Closure</classname></link>.
|
|
</simpara>
|
|
|
|
<sect2 role="changelog">
|
|
&reftitle.changelog;
|
|
<para>
|
|
<informaltable>
|
|
<tgroup cols="2">
|
|
<thead>
|
|
<row>
|
|
<entry>&Version;</entry>
|
|
<entry>&Description;</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>5.4.0</entry>
|
|
<entry>
|
|
<varname>$this</varname> puede ser usado en funciones anónimas.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>5.3.0</entry>
|
|
<entry>
|
|
Las funciones anónimas se encuentran disponibles.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 role="notes">
|
|
&reftitle.notes;
|
|
<note>
|
|
<simpara>
|
|
Es posible usar <function>func_num_args</function>,
|
|
<function>func_get_arg</function>, y <function>func_get_args</function>
|
|
desde dentro de una clausura.
|
|
</simpara>
|
|
</note>
|
|
</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
|
|
-->
|