Lección 20 de 75 10 min de lectura

Definir Funciones

Las funciones son bloques de código reutilizables que realizan una tarea específica. Permiten organizar tu código, evitar repeticiones y hacer programas más fáciles de mantener y depurar.

¿Qué es una función?

Una función es un conjunto de instrucciones agrupadas bajo un nombre. Puedes llamar a esa función cuando la necesites, pasarle datos (argumentos) y obtener un resultado de vuelta.

PHP
<?php

declare(strict_types=1);

// Definir una función simple
function saludar(): void
{
    echo "¡Hola, mundo!\n";
}

// Llamar a la función
saludar(); // ¡Hola, mundo!
saludar(); // ¡Hola, mundo!
saludar(); // ¡Hola, mundo!

Sintaxis básica

La estructura de una función en PHP moderno es:

PHP
<?php

declare(strict_types=1);

// Función sin parámetros ni retorno
function mostrarBienvenida(): void
{
    echo "Bienvenido al sistema\n";
}

// Función con parámetros tipados y tipo de retorno
function sumar(int $a, int $b): int
{
    return $a + $b;
}

// Llamar y usar el resultado
$resultado = sumar(5, 3);
echo $resultado; // 8
declare(strict_types=1)

Esta declaración activa el modo estricto de tipos. PHP lanzará un error si pasas un tipo incorrecto a una función. Siempre úsalo en código moderno.

Convenciones de nombres

PHP no distingue entre mayúsculas y minúsculas en los nombres de funciones, pero es importante seguir convenciones consistentes:

PHP
<?php

declare(strict_types=1);

// ✓ camelCase (recomendado en PHP moderno y frameworks)
function calcularTotal(float $precio, int $cantidad): float
{
    return $precio * $cantidad;
}

// ✓ snake_case (estilo PHP tradicional)
function calcular_total(float $precio, int $cantidad): float
{
    return $precio * $cantidad;
}

// ✗ Evitar: nombres poco descriptivos
function ct(float $p, int $c): float
{
    return $p * $c;
}

// ✗ Evitar: nombres que empiecen con números
// function 2sumar() {} // Error de sintaxis
Nombres descriptivos

Usa verbos que describan lo que hace la función: obtenerUsuario(), calcularDescuento(), validarEmail(). Un buen nombre hace que el código se documente solo.

Funciones con parámetros tipados

Los parámetros permiten pasar datos a la función. En PHP moderno, siempre debes tipar los parámetros:

PHP
<?php

declare(strict_types=1);

// Un parámetro tipado
function saludarA(string $nombre): void
{
    echo "¡Hola, $nombre!\n";
}

saludarA('Ana');   // ¡Hola, Ana!
saludarA('Pedro'); // ¡Hola, Pedro!

// Múltiples parámetros tipados
function presentar(string $nombre, int $edad, string $ciudad): void
{
    echo "$nombre tiene $edad años y vive en $ciudad.\n";
}

presentar('Laura', 28, 'Madrid');
// Laura tiene 28 años y vive en Madrid.

// Los parámetros son variables locales
function duplicar(int $numero): int
{
    $numero = $numero * 2;
    return $numero;
}

$valor = 5;
$resultado = duplicar($valor);
echo $valor;     // 5 (no cambió)
echo $resultado; // 10

Valores por defecto

Puedes asignar valores por defecto a los parámetros. Si no se pasa un argumento, se usa el valor por defecto:

PHP
<?php

declare(strict_types=1);

function saludar(string $nombre = 'visitante'): void
{
    echo "¡Hola, $nombre!\n";
}

saludar();        // ¡Hola, visitante!
saludar('María'); // ¡Hola, María!

// Múltiples valores por defecto
/**
 * @return array{nombre: string, rol: string, activo: bool}
 */
function crearUsuario(string $nombre, string $rol = 'usuario', bool $activo = true): array
{
    return [
        'nombre' => $nombre,
        'rol' => $rol,
        'activo' => $activo,
    ];
}

$admin = crearUsuario('Admin', 'administrador', true);
$user = crearUsuario('Juan');  // rol='usuario', activo=true

print_r($user);
/*
Array
(
    [nombre] => Juan
    [rol] => usuario
    [activo] => 1
)
*/
Orden de los parámetros

Los parámetros con valores por defecto deben ir después de los parámetros obligatorios. function foo(string $a = '', string $b) causará problemas.

Retornar valores con tipo

Usa return para devolver un valor desde la función. Siempre especifica el tipo de retorno:

PHP
<?php

declare(strict_types=1);

function sumar(float $a, float $b): float
{
    return $a + $b;
}

$total = sumar(10.5, 20.3);
echo $total; // 30.8

// return termina la función inmediatamente
function verificarEdad(int $edad): string
{
    if ($edad < 0) {
        return 'Edad inválida';
    }

    if ($edad >= 18) {
        return 'Mayor de edad';
    }

    return 'Menor de edad';
}

echo verificarEdad(25);  // Mayor de edad
echo verificarEdad(15);  // Menor de edad
echo verificarEdad(-5);  // Edad inválida

// Retornar un array tipado
/**
 * @param array<int> $numeros
 * @return array{suma: int|float, promedio: float, cantidad: int}
 */
function calcularEstadisticas(array $numeros): array
{
    $cantidad = count($numeros);
    $suma = array_sum($numeros);

    return [
        'suma' => $suma,
        'promedio' => $cantidad > 0 ? $suma / $cantidad : 0.0,
        'cantidad' => $cantidad,
    ];
}

$stats = calcularEstadisticas([10, 20, 30, 40]);
echo $stats['promedio']; // 25

Tipos de retorno especiales

PHP
<?php

declare(strict_types=1);

// void: la función no retorna nada
function mostrarMensaje(string $mensaje): void
{
    echo $mensaje . "\n";
    // No usar return con valor, o simplemente no usar return
}

// Tipo nullable: puede retornar el tipo o null
function buscarUsuario(int $id): ?array
{
    $usuarios = [
        1 => ['nombre' => 'Ana', 'email' => 'ana@example.com'],
        2 => ['nombre' => 'Luis', 'email' => 'luis@example.com'],
    ];

    return $usuarios[$id] ?? null;
}

$usuario = buscarUsuario(1);  // ['nombre' => 'Ana', ...]
$noExiste = buscarUsuario(99); // null

// Union types (PHP 8+): puede retornar varios tipos
function dividir(float $a, float $b): float|string
{
    if ($b === 0.0) {
        return 'No se puede dividir por cero';
    }

    return $a / $b;
}

echo dividir(10, 2);  // 5
echo dividir(10, 0);  // No se puede dividir por cero

Ámbito de variables (scope)

Las variables definidas dentro de una función son locales y no son accesibles fuera de ella:

PHP
<?php

declare(strict_types=1);

$global = 'Soy global';

function mostrar(): void
{
    $local = 'Soy local';
    echo $local . "\n";

    // $global no está definida aquí
    // echo $global; // Warning: Undefined variable
}

mostrar();          // Soy local
echo $global;       // Soy global
// echo $local;     // Error: variable no definida

// ❌ NO RECOMENDADO: usar global
$contador = 0;

function incrementarMal(): void
{
    global $contador;
    $contador++;
}

// ✅ RECOMENDADO: pasar como parámetro y retornar
function incrementar(int $valor): int
{
    return $valor + 1;
}

$contador = 0;
$contador = incrementar($contador);
$contador = incrementar($contador);
echo $contador; // 2
Evita global

La palabra clave global crea dependencias ocultas y hace el código difícil de mantener y probar. Prefiere siempre pasar datos como parámetros.

Verificar si existe una función

PHP
<?php

declare(strict_types=1);

function miFuncion(): string
{
    return 'Hola';
}

// Verificar si existe
if (function_exists('miFuncion')) {
    echo miFuncion();
}

// Útil para polyfills
if (!function_exists('array_is_list')) {
    // Polyfill para PHP < 8.1
    function array_is_list(array $array): bool
    {
        return $array === [] || array_keys($array) === range(0, count($array) - 1);
    }
}

Ejemplo práctico

PHP
<?php

declare(strict_types=1);

// Sistema de carrito de compras simple

/**
 * @return array{nombre: string, precio: float, cantidad: int}
 */
function crearProducto(string $nombre, float $precio, int $cantidad = 1): array
{
    return [
        'nombre' => $nombre,
        'precio' => $precio,
        'cantidad' => $cantidad,
    ];
}

/**
 * @param array{nombre: string, precio: float, cantidad: int} $producto
 */
function calcularSubtotal(array $producto): float
{
    return $producto['precio'] * $producto['cantidad'];
}

/**
 * @param array<array{nombre: string, precio: float, cantidad: int}> $carrito
 */
function calcularTotal(array $carrito): float
{
    $total = 0.0;

    foreach ($carrito as $producto) {
        $total += calcularSubtotal($producto);
    }

    return $total;
}

function aplicarDescuento(float $total, int $porcentaje = 10): float
{
    $descuento = $total * ($porcentaje / 100);
    return $total - $descuento;
}

function formatearPrecio(float $cantidad): string
{
    return number_format($cantidad, 2, ',', '.') . ' €';
}

// Usar las funciones
$carrito = [
    crearProducto('Camiseta', 19.99, 2),
    crearProducto('Pantalón', 39.99),
    crearProducto('Zapatos', 59.99),
];

$total = calcularTotal($carrito);
$totalConDescuento = aplicarDescuento($total, 15);

echo 'Subtotal: ' . formatearPrecio($total) . "\n";
echo 'Total con 15% dto: ' . formatearPrecio($totalConDescuento) . "\n";

// Subtotal: 139,96 €
// Total con 15% dto: 118,97 €

Ejercicios

Ejercicio 1: Funcion de saludo personalizado

Crea una funcion llamada saludarPersona que reciba un nombre (string) y una hora del dia (int, 0-23). Debe retornar un saludo apropiado: "Buenos dias, [nombre]" (6-11), "Buenas tardes, [nombre]" (12-19), o "Buenas noches, [nombre]" (20-5).

Ver solucion
PHP
<?php
declare(strict_types=1);

function saludarPersona(string $nombre, int $hora): string
{
    if ($hora >= 6 && $hora <= 11) {
        return "Buenos dias, $nombre";
    }

    if ($hora >= 12 && $hora <= 19) {
        return "Buenas tardes, $nombre";
    }

    return "Buenas noches, $nombre";
}

echo saludarPersona('Ana', 9);   // Buenos dias, Ana
echo saludarPersona('Luis', 15); // Buenas tardes, Luis
echo saludarPersona('Eva', 22);  // Buenas noches, Eva

Ejercicio 2: Calculadora de area

Crea una funcion calcularAreaRectangulo que reciba el ancho y alto (ambos float) y retorne el area. Incluye un valor por defecto de 1.0 para el alto.

Ver solucion
PHP
<?php
declare(strict_types=1);

function calcularAreaRectangulo(float $ancho, float $alto = 1.0): float
{
    return $ancho * $alto;
}

echo calcularAreaRectangulo(5.0, 3.0); // 15.0
echo calcularAreaRectangulo(4.0);      // 4.0 (usa alto = 1.0)

Ejercicio 3: Validador de password

Crea una funcion esPasswordValido que reciba una password (string) y retorne true si tiene al menos 8 caracteres, o false en caso contrario.

Ver solucion
PHP
<?php
declare(strict_types=1);

function esPasswordValido(string $password): bool
{
    return strlen($password) >= 8;
}

var_dump(esPasswordValido('abc'));        // false
var_dump(esPasswordValido('12345678'));   // true
var_dump(esPasswordValido('miPassword')); // true

¿Te está gustando el curso?

Tenemos cursos premium con proyectos reales y soporte personalizado.

Descubrir cursos premium