20 ejercicios avanzados de PHP resueltos: POO, MySQL, seguridad y MVC

Estos 20 ejercicios avanzados de PHP resueltos están pensados para quienes ya dominan sintaxis, formularios, PDO y bases de datos y quieren practicar conceptos de aplicaciones reales.

Vas a trabajar con POO, seguridad, autenticación, roles, consultas preparadas, MVC y Composer.

1. Crear una clase Producto

<?php
class Producto
{
    public function __construct(
        private string $nombre,
        private float $precio
    ) {
    }

    public function getNombre(): string
    {
        return $this->nombre;
    }

    public function getPrecio(): float
    {
        return $this->precio;
    }
}
?>

2. Encapsular el stock de un producto

public function descontarStock(int $cantidad): void
{
    if ($cantidad <= 0 || $cantidad > $this->stock) {
        throw new InvalidArgumentException('Stock inválido');
    }

    $this->stock -= $cantidad;
}

3. Crear una interfaz de notificaciones

interface Notificable
{
    public function enviar(string $mensaje): void;
}

4. Implementar notificaciones por email

class EmailNotificacion implements Notificable
{
    public function enviar(string $mensaje): void
    {
        echo 'Email: ' . $mensaje;
    }
}

5. Crear un repositorio con PDO

class ProductoRepository
{
    public function __construct(
        private PDO $pdo
    ) {
    }

    public function todos(): array
    {
        return $this->pdo
            ->query('SELECT * FROM productos')
            ->fetchAll(PDO::FETCH_ASSOC);
    }
}

6. Buscar por ID con una consulta preparada

public function buscar(int $id): ?array
{
    $stmt = $this->pdo->prepare(
        'SELECT * FROM productos WHERE id = :id'
    );

    $stmt->execute(['id' => $id]);

    $resultado = $stmt->fetch(PDO::FETCH_ASSOC);

    return $resultado ?: null;
}

7. Implementar una transacción

$pdo->beginTransaction();

try {
    // operaciones relacionadas

    $pdo->commit();
} catch (Throwable $e) {
    $pdo->rollBack();
    throw $e;
}

8. Login seguro con password_verify()

if (
    $usuario &&
    password_verify($password, $usuario['password'])
) {
    session_regenerate_id(true);

    $_SESSION['usuario_id'] = $usuario['id'];
}

9. Middleware simple de autenticación

function requireLogin(): void
{
    if (!isset($_SESSION['usuario_id'])) {
        header('Location: /login.php');
        exit;
    }
}

10. Controlar acceso por rol

function requireAdmin(): void
{
    requireLogin();

    if ($_SESSION['rol'] !== 'admin') {
        http_response_code(403);
        exit('Acceso denegado');
    }
}

11. Generar un token CSRF

if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

12. Validar el token CSRF

if (
    !isset($_POST['csrf_token']) ||
    !hash_equals(
        $_SESSION['csrf_token'],
        $_POST['csrf_token']
    )
) {
    http_response_code(403);
    exit;
}

13. Crear una capa de servicio

class ProductoService
{
    public function __construct(
        private ProductoRepository $repository
    ) {
    }

    public function listarActivos(): array
    {
        return array_filter(
            $this->repository->todos(),
            fn($producto) => $producto['activo']
        );
    }
}

14. Crear un controlador MVC

class ProductoController
{
    public function __construct(
        private ProductoService $service
    ) {
    }

    public function index(): void
    {
        $productos = $this->service->listarActivos();

        require '../Views/productos/index.php';
    }
}

15. Crear un router simple

$ruta = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

switch ($ruta) {
    case '/productos':
        $controller->index();
        break;

    default:
        http_response_code(404);
}

16. Usar namespaces

<?php

namespace App\Services;

class ProductoService
{
}
?>

17. Configurar autoload PSR-4

{
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        }
    }
}

Después:

composer dump-autoload

18. Crear una búsqueda paginada con PDO

$buscar = trim($_GET['buscar'] ?? '');
$pagina = max(1, (int) ($_GET['pagina'] ?? 1));
$limite = 20;
$offset = ($pagina - 1) * $limite;

$stmt = $pdo->prepare(
    'SELECT *
     FROM productos
     WHERE nombre LIKE :buscar
     ORDER BY id DESC
     LIMIT :limite OFFSET :offset'
);

$stmt->bindValue(':buscar', '%' . $buscar . '%');
$stmt->bindValue(':limite', $limite, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();

19. Registrar errores en un archivo

try {
    // operación
} catch (Throwable $e) {
    error_log(
        $e->getMessage() . PHP_EOL,
        3,
        __DIR__ . '/app.log'
    );
}

20. Diseñar un mini sistema MVC completo

Objetivo: construir una aplicación de gestión de productos con:

  • login;
  • roles;
  • CRUD;
  • PDO;
  • consultas preparadas;
  • CSRF;
  • arquitectura MVC;
  • autoload PSR-4;
  • validación;
  • paginación y búsqueda.

Una estructura posible:

app/
├── Controllers/
├── Models/
├── Repositories/
├── Services/
└── Views/

config/
public/
vendor/
composer.json

¿Qué deberías poder hacer después?

Si podés resolver estos desafíos entendiendo cada parte, ya tenés una base muy sólida de PHP moderno y estás en condiciones de comenzar a trabajar con frameworks como Laravel con mucha más claridad.

Serie de ejercicios de PHP

También podés ver todos los contenidos prácticos en la sección Ejercicios resueltos.

¿Te sirvió esta guía? ☕

☕ Apoyar con Mercado Pago

🌎 Apoyar con PayPal

20 ejercicios intermedios de PHP resueltos: arrays, funciones, formularios y PDO

Si ya dominás variables, condicionales, bucles y funciones, estos 20 ejercicios intermedios de PHP resueltos te van a ayudar a combinar conceptos y acercarte a problemas reales.

1. Filtrar números pares de un array

<?php
$numeros = [1,2,3,4,5,6,7,8];

$pares = array_filter($numeros, fn($n) => $n % 2 === 0);

print_r($pares);
?>

2. Ordenar productos por precio

<?php
$productos = [
    ['nombre' => 'Mouse', 'precio' => 15000],
    ['nombre' => 'Monitor', 'precio' => 180000],
    ['nombre' => 'Teclado', 'precio' => 25000]
];

usort($productos, fn($a, $b) => $a['precio'] <=> $b['precio']);

print_r($productos);
?>

3. Buscar un usuario por email

<?php
$usuarios = [
    ['nombre' => 'Ana', 'email' => 'ana@mail.com'],
    ['nombre' => 'Juan', 'email' => 'juan@mail.com']
];

$emailBuscado = 'juan@mail.com';

$resultado = array_filter($usuarios, fn($u) => $u['email'] === $emailBuscado);

print_r($resultado);
?>

4. Eliminar duplicados

<?php
$valores = [1,2,2,3,4,4,5];

$unicos = array_unique($valores);

print_r($unicos);
?>

5. Contar palabras de un texto

<?php
$texto = 'PHP es simple de aprender y muy utilizado';

echo str_word_count($texto);
?>

6. Validar un email

<?php
$email = 'usuario@email.com';

if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo 'Email válido';
} else {
    echo 'Email inválido';
}
?>

7. Validar un formulario POST

<?php
$nombre = trim($_POST['nombre'] ?? '');

if ($nombre === '') {
    echo 'El nombre es obligatorio';
}
?>

8. Mantener valores del formulario

<input
    type="text"
    name="nombre"
    value="<?= htmlspecialchars($_POST['nombre'] ?? '') ?>"
>

9. Generar una contraseña aleatoria

<?php
$caracteres = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$password = '';

for ($i = 0; $i < 12; $i++) {
    $password .= $caracteres[random_int(0, strlen($caracteres) - 1)];
}

echo $password;
?>

10. Guardar una contraseña con password_hash()

<?php
$password = 'ClaveSegura123';

$hash = password_hash($password, PASSWORD_DEFAULT);

echo $hash;
?>

11. Comprobar una contraseña

<?php
if (password_verify($password, $hash)) {
    echo 'Contraseña correcta';
}
?>

12. Crear una sesión de usuario

<?php
session_start();

$_SESSION['usuario_id'] = 10;
$_SESSION['nombre'] = 'Ana';
?>

13. Proteger una página con sesión

<?php
session_start();

if (!isset($_SESSION['usuario_id'])) {
    header('Location: login.php');
    exit;
}
?>

14. Leer un archivo de texto

<?php
$contenido = file_get_contents('datos.txt');

echo nl2br(htmlspecialchars($contenido));
?>

15. Guardar datos en un archivo

<?php
$texto = "Nueva línea
";

file_put_contents(
    'datos.txt',
    $texto,
    FILE_APPEND
);
?>

16. Conectarse a MySQL con PDO

<?php
$pdo = new PDO(
    'mysql:host=localhost;dbname=tienda;charset=utf8mb4',
    'root',
    ''
);

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
?>

17. Buscar un registro con una consulta preparada

<?php
$stmt = $pdo->prepare(
    'SELECT * FROM productos WHERE id = :id'
);

$stmt->execute([
    'id' => 5
]);

$producto = $stmt->fetch(PDO::FETCH_ASSOC);
?>

18. Insertar un producto con PDO

<?php
$stmt = $pdo->prepare(
    'INSERT INTO productos (nombre, precio)
     VALUES (:nombre, :precio)'
);

$stmt->execute([
    'nombre' => 'Teclado',
    'precio' => 25000
]);
?>

19. Crear una paginación básica

<?php
$pagina = max(1, (int) ($_GET['pagina'] ?? 1));
$porPagina = 10;
$offset = ($pagina - 1) * $porPagina;

$stmt = $pdo->prepare(
    'SELECT * FROM productos LIMIT :limite OFFSET :offset'
);

$stmt->bindValue(':limite', $porPagina, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
?>

20. Crear un filtro de búsqueda

<?php
$buscar = trim($_GET['buscar'] ?? '');

$stmt = $pdo->prepare(
    'SELECT * FROM productos
     WHERE nombre LIKE :buscar'
);

$stmt->execute([
    'buscar' => '%' . $buscar . '%'
]);

$productos = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

¿Qué sigue?

Si podés resolver estos ejercicios sin copiar las soluciones, ya estás listo para trabajar con desafíos avanzados: POO, seguridad, relaciones entre clases, arquitectura MVC y proyectos completos.

Serie de ejercicios de PHP

También podés ver todos los contenidos prácticos en la sección Ejercicios resueltos.

¿Te sirvió esta guía? ☕

☕ Apoyar con Mercado Pago

🌎 Apoyar con PayPal

20 ejercicios de PHP para principiantes resueltos paso a paso

Si estás aprendiendo PHP desde cero, practicar es una de las mejores formas de fijar conceptos. En esta guía vas a encontrar 20 ejercicios de PHP para principiantes resueltos paso a paso.

Los ejercicios trabajan variables, operadores, condicionales, bucles, arrays y funciones.

1. Mostrar un mensaje

Ejercicio: mostrar el texto “Hola Mundo desde PHP”.

<?php
echo 'Hola Mundo desde PHP';
?>

2. Sumar dos números

<?php
$a = 10;
$b = 5;

$suma = $a + $b;

echo $suma;
?>

3. Calcular el promedio de tres números

<?php
$a = 8;
$b = 7;
$c = 9;

$promedio = ($a + $b + $c) / 3;

echo $promedio;
?>

4. Saber si un número es par o impar

<?php
$numero = 7;

if ($numero % 2 === 0) {
    echo 'Es par';
} else {
    echo 'Es impar';
}
?>

5. Saber si una persona es mayor de edad

<?php
$edad = 20;

if ($edad >= 18) {
    echo 'Es mayor de edad';
} else {
    echo 'Es menor de edad';
}
?>

6. Obtener el mayor de dos números

<?php
$a = 15;
$b = 22;

if ($a > $b) {
    echo $a;
} else {
    echo $b;
}
?>

7. Mostrar números del 1 al 10

<?php
for ($i = 1; $i <= 10; $i++) {
    echo $i . '<br>';
}
?>

8. Mostrar números pares del 1 al 20

<?php
for ($i = 2; $i <= 20; $i += 2) {
    echo $i . '<br>';
}
?>

9. Tabla de multiplicar

<?php
$numero = 5;

for ($i = 1; $i <= 10; $i++) {
    echo $numero . ' x ' . $i . ' = ' . ($numero * $i) . '<br>';
}
?>

10. Sumar números del 1 al 100

<?php
$suma = 0;

for ($i = 1; $i <= 100; $i++) {
    $suma += $i;
}

echo $suma;
?>

11. Contar caracteres de una palabra

<?php
$palabra = 'programacion';

echo strlen($palabra);
?>

12. Convertir texto a mayúsculas

<?php
$texto = 'hola php';

echo strtoupper($texto);
?>

13. Recorrer un array

<?php
$frutas = ['Manzana', 'Banana', 'Naranja'];

foreach ($frutas as $fruta) {
    echo $fruta . '<br>';
}
?>

14. Encontrar el mayor valor de un array

<?php
$numeros = [4, 9, 2, 15, 6];

echo max($numeros);
?>

15. Calcular el promedio de un array

<?php
$notas = [8, 7, 9, 10];

$promedio = array_sum($notas) / count($notas);

echo $promedio;
?>

16. Crear una función para saludar

<?php
function saludar(string $nombre): string
{
    return 'Hola ' . $nombre;
}

echo saludar('Ana');
?>

17. Función para calcular el área de un rectángulo

<?php
function areaRectangulo(float $base, float $altura): float
{
    return $base * $altura;
}

echo areaRectangulo(5, 3);
?>

18. Determinar si un número es positivo, negativo o cero

<?php
$numero = -3;

if ($numero > 0) {
    echo 'Positivo';
} elseif ($numero < 0) {
    echo 'Negativo';
} else {
    echo 'Cero';
}
?>

19. Contar cuántas veces aparece un valor

<?php
$numeros = [1, 2, 3, 2, 4, 2];

$resultado = array_count_values($numeros);

echo $resultado[2];
?>

20. Generar un número aleatorio

<?php
$numero = random_int(1, 100);

echo $numero;
?>

¿Qué practicar después?

Si estos ejercicios ya te resultan sencillos, el siguiente paso es trabajar con problemas intermedios que mezclen arrays, funciones, formularios, validación y acceso a bases de datos.

Serie de ejercicios de PHP

También podés ver todos los contenidos prácticos en la sección Ejercicios resueltos.

¿Te sirvió esta guía? ☕

☕ Apoyar con Mercado Pago

🌎 Apoyar con PayPal