Leccion 47 de 75 10 min de lectura

Nuevas Funciones en PHP 8.x

PHP 8.x introduce numerosas funciones nuevas que simplifican tareas comunes. Desde busquedas en strings hasta validacion de arrays, estas funciones hacen el codigo mas legible y expresivo.

Funciones de strings (PHP 8.0)

Tres funciones esperadas por mucho tiempo finalmente llegaron en PHP 8.0. Antes requerias strpos con comparaciones estrictas:

PHP
<?php

declare(strict_types=1);

$texto = 'Bienvenido al curso de PHP';

// str_contains: verifica si contiene un substring
var_dump(str_contains($texto, 'curso')); // true
var_dump(str_contains($texto, 'java'));  // false

// str_starts_with: verifica si empieza con
var_dump(str_starts_with($texto, 'Bienvenido')); // true
var_dump(str_starts_with($texto, 'bienvenido')); // false (sensible a mayusculas)

// str_ends_with: verifica si termina con
var_dump(str_ends_with($texto, 'PHP'));    // true
var_dump(str_ends_with($texto, 'Python')); // false

// Comparacion con el metodo antiguo
// Antes:
if (strpos($texto, 'curso') !== false) {
    echo 'Contiene "curso"';
}

// Ahora:
if (str_contains($texto, 'curso')) {
    echo 'Contiene "curso"';
}

Funciones de arrays (PHP 8.1)

array_is_list

Verifica si un array es una lista (indices numericos consecutivos desde 0):

PHP
<?php

declare(strict_types=1);

// Es lista: indices 0, 1, 2...
$lista = ['manzana', 'pera', 'naranja'];
var_dump(array_is_list($lista)); // true

// No es lista: tiene claves string
$asociativo = ['fruta' => 'manzana', 'color' => 'rojo'];
var_dump(array_is_list($asociativo)); // false

// No es lista: indices no consecutivos
$huecos = [0 => 'a', 2 => 'b'];
var_dump(array_is_list($huecos)); // false

// No es lista: no empieza en 0
$desplazado = [1 => 'a', 2 => 'b'];
var_dump(array_is_list($desplazado)); // false

// Array vacio es lista
var_dump(array_is_list([])); // true

// Uso practico: validar datos JSON
function procesarDatos(array $items): void
{
    if (!array_is_list($items)) {
        throw new \InvalidArgumentException('Se esperaba una lista');
    }

    foreach ($items as $item) {
        // Procesar cada elemento
    }
}

Funciones para enums (PHP 8.1)

PHP
<?php

declare(strict_types=1);

enum Estado
{
    case Pendiente;
    case Procesando;
    case Completado;
}

// enum_exists: verifica si existe un enum
var_dump(enum_exists('Estado'));     // true
var_dump(enum_exists('NoExiste'));   // false

// Uso con autoloading
if (enum_exists('App\\Enums\\TipoUsuario')) {
    // El enum esta disponible
}

Funciones de primera clase (PHP 8.1)

PHP 8.1 introduce una sintaxis para crear closures a partir de funciones y metodos existentes:

PHP
<?php

declare(strict_types=1);

// Antes: crear closure de funcion existente
$mayusculas = fn (string $s): string => strtoupper($s);

// PHP 8.1: sintaxis mas limpia con (...)
$mayusculas = strtoupper(...);
$resultado = $mayusculas('hola'); // 'HOLA'

// Funciona con funciones, metodos estaticos y de instancia
class Calculadora
{
    public function sumar(int $a, int $b): int
    {
        return $a + $b;
    }

    public static function multiplicar(int $a, int $b): int
    {
        return $a * $b;
    }
}

// Metodo estatico
$multiplicar = Calculadora::multiplicar(...);
echo $multiplicar(3, 4); // 12

// Metodo de instancia
$calc = new Calculadora();
$sumar = $calc->sumar(...);
echo $sumar(5, 3); // 8

// Util con funciones de orden superior
$numeros = [1, 2, 3, 4, 5];
$dobles = array_map(fn ($n) => $n * 2, $numeros);

// Con funciones built-in
$textos = ['  hola  ', '  mundo  '];
$limpios = array_map(trim(...), $textos);
print_r($limpios); // ['hola', 'mundo']

Nuevas funciones en PHP 8.2

PHP
<?php

declare(strict_types=1);

// mysqli_execute_query: ejecuta y obtiene resultados en una llamada
// $result = mysqli_execute_query($conn, 'SELECT * FROM users WHERE id = ?', [$id]);

// Constantes para validar datos sensibles
// FILTER_VALIDATE_BOOL ahora es alias de FILTER_VALIDATE_BOOLEAN

// ini_parse_quantity: convierte valores como '128M' a bytes
$memoria = ini_parse_quantity('128M');
echo $memoria; // 134217728

$disco = ini_parse_quantity('1G');
echo $disco; // 1073741824

// Util para leer configuraciones
$maxUpload = ini_parse_quantity(ini_get('upload_max_filesize'));
echo "Max upload: $maxUpload bytes";

// memory_reset_peak_usage: reinicia el contador de pico de memoria
// Util para benchmarks
memory_reset_peak_usage();
// ... codigo a medir ...
$pico = memory_get_peak_usage();
echo "Pico de memoria: $pico bytes";

Nuevas funciones en PHP 8.3

PHP
<?php

declare(strict_types=1);

// json_validate: valida JSON sin decodificarlo
$jsonValido = '{"nombre": "Ana", "edad": 25}';
$jsonInvalido = '{nombre: Ana}';

var_dump(json_validate($jsonValido));   // true
var_dump(json_validate($jsonInvalido)); // false

// Mas eficiente que json_decode cuando solo necesitas validar
if (json_validate($input)) {
    $datos = json_decode($input, true);
    // Procesar datos
} else {
    throw new \InvalidArgumentException('JSON invalido');
}

// Override de metodos con #[\Override]
// El atributo verifica que el metodo realmente sobrescribe algo

class Animal
{
    public function hacerSonido(): string
    {
        return 'sonido';
    }
}

class Perro extends Animal
{
    #[\Override]
    public function hacerSonido(): string
    {
        return 'guau';
    }

    // Esto daria error: el metodo no existe en el padre
    // #[\Override]
    // public function correr(): void {}
}

// Constantes de clase tipadas
class Configuracion
{
    public const string APP_NAME = 'MiApp';
    public const int MAX_INTENTOS = 3;
    public const array OPCIONES = ['debug', 'log'];
}

Funciones de fecha y hora

PHP
<?php

declare(strict_types=1);

// PHP 8.3: DateTimeInterface::createFromTimestamp
$fecha = DateTimeImmutable::createFromTimestamp(1700000000);
echo $fecha->format('Y-m-d H:i:s'); // 2023-11-14 22:13:20

// Milisegundos
$fechaMs = DateTimeImmutable::createFromTimestamp(1700000000.123);

// PHP 8.3: getMicrosecond y setMicrosecond
$ahora = new DateTimeImmutable();
echo $ahora->getMicrosecond(); // ej: 123456

$conMicros = $ahora->setMicrosecond(500000);

// Metodos estaticos en DateTime (PHP 8.2+)
$fecha1 = DateTime::createFromImmutable(new DateTimeImmutable());
$fecha2 = DateTimeImmutable::createFromMutable(new DateTime());

Resumen por versión

PHP
<?php

declare(strict_types=1);

/*
PHP 8.0:
- str_contains($haystack, $needle)
- str_starts_with($haystack, $needle)
- str_ends_with($haystack, $needle)
- fdiv() - division con manejo de infinito
- get_debug_type() - tipo real para debug
- get_resource_id() - ID de recurso

PHP 8.1:
- array_is_list($array)
- enum_exists($enum)
- fsync() / fdatasync() - sincronizar archivos
- Sintaxis funcion(...) para closures

PHP 8.2:
- ini_parse_quantity($value)
- memory_reset_peak_usage()
- mysqli_execute_query()

PHP 8.3:
- json_validate($json)
- #[\Override] atributo
- Constantes tipadas en clases
- DateTimeImmutable::createFromTimestamp()
*/

Ejercicios

Ejercicio 1: Validador de URL

Crea una funcion que valide si una URL es segura (https) y pertenece a un dominio permitido.

Ver solucion
PHP
<?php

declare(strict_types=1);

function validarUrl(string $url, array $dominiosPermitidos): bool
{
    // Debe empezar con https
    if (!str_starts_with($url, 'https://')) {
        return false;
    }

    // Verificar si contiene algun dominio permitido
    foreach ($dominiosPermitidos as $dominio) {
        if (str_contains($url, $dominio)) {
            return true;
        }
    }

    return false;
}

$permitidos = ['github.com', 'gitlab.com'];

var_dump(validarUrl('https://github.com/user/repo', $permitidos)); // true
var_dump(validarUrl('http://github.com/user/repo', $permitidos));  // false
var_dump(validarUrl('https://evil.com/hack', $permitidos));        // false

Ejercicio 2: Validar estructura JSON

Crea una funcion que reciba un string JSON y valide que sea un JSON valido con una lista de objetos (no un objeto simple).

Ver solucion
PHP
<?php

declare(strict_types=1);

function validarListaJson(string $json): bool
{
    // Primero validar que sea JSON valido
    if (!json_validate($json)) {
        return false;
    }

    // Decodificar y verificar que sea lista
    $datos = json_decode($json, true);

    return is_array($datos) && array_is_list($datos);
}

$lista = '[{"id": 1}, {"id": 2}]';
$objeto = '{"nombre": "Ana"}';
$invalido = '{mal json}';

var_dump(validarListaJson($lista));    // true
var_dump(validarListaJson($objeto));   // false
var_dump(validarListaJson($invalido)); // false

Ejercicio 3: Procesar textos con closures

Usa la sintaxis de funciones de primera clase para limpiar un array de strings: quitar espacios, convertir a minusculas y capitalizar la primera letra.

Ver solucion
PHP
<?php

declare(strict_types=1);

function limpiarTextos(array $textos): array
{
    // Aplicar transformaciones en secuencia
    $textos = array_map(trim(...), $textos);
    $textos = array_map(strtolower(...), $textos);
    $textos = array_map(ucfirst(...), $textos);

    return $textos;
}

$entrada = ['  HOLA  ', '  MUNDO  ', '  PHP  '];
$salida = limpiarTextos($entrada);

print_r($salida);
// ['Hola', 'Mundo', 'Php']

¿Te está gustando el curso?

Cursos premium con proyectos reales y soporte.

Descubrir cursos premium