Composite DB: ORM Ultraligero para PHP Moderno – Implementa Velocidad en tus Soluciones

Si hay algo que me apasiona en el desarrollo web, es encontrar herramientas que simplifiquen la vida sin comprometer el rendimiento. ORMs como Doctrine son potentes, pero a menudo vienen con configuraciones complejas y una curva de aprendizaje empinada. Hace poco me encontré Composite DB, un ORM minimalista que puedes tener funcionando en menos de 5 minutos. ¿Te gustaría conocer una opción ligera y rápida para tus proyectos en PHP 8.1+? ¡Sigue leyendo!

¿Qué es Composite DB?

Composite DB es un ORM ultraligero diseñado para PHP 8.1+. Su filosofía es clara: menos configuración, más acción. Aprovecha las características modernas de PHP para ofrecerte un código limpio y un rendimiento ágil, ideal para proyectos donde la velocidad y la simplicidad son prioridad.

Lo mejor de PHP 8.1+ en tus manos

Composite DB saca el máximo provecho de las novedades de PHP. Mira este ejemplo de una entidad:

<?php // src/Entity/User.php namespace App\Entity; use Composite\DB\Attributes\{Table, PrimaryKey}; use Composite\Entity\AbstractEntity; use App\Enums\Status; #[Table(connection: 'sqlite', name: 'Users')] class User extends AbstractEntity { #[PrimaryKey(autoIncrement: true)] public readonly int $id; public function __construct( public string $email, public ?string $name = null, public bool $is_test = false, public Status $status = Status::ACTIVE, public readonly \DateTimeImmutable $created_at = new \DateTimeImmutable(), ) {} }

  • Enums nativos: Usa Status para definir estados como ACTIVE o BLOCKED de forma clara.
  • Propiedades inmutables: id y created_at son readonly, garantizando datos consistentes.
  • Atributos PHP: Con #[Table] y #[PrimaryKey], mapeas la entidad a la base de datos sin complicaciones.

¿Cuándo brilla Composite DB?

Este ORM es perfecto para escenarios donde necesitas moverte rápido:

  • APIs RESTful: Crea endpoints para apps móviles en minutos.
  • Prototipos rápidos: Valida ideas sin perder tiempo en configuraciones.
  • Proyectos IoT: Gestiona datos de sensores con pocos recursos.

Tutorial práctico: API con Composite DB y Slim Framework

Vamos a construir una API sencilla usando Composite DB y Slim con SQLite como base de datos. ¡Sigue estos pasos y tendrás algo funcional en poco tiempo!

1.- Instalar dependencias

Crea un nuevo proyecto e instala las dependencias con Composer:

mkdir CompositeDB-Slim cd CompositeDB-Slim composer init --name="tu-nombre/composite-db-slim" --require="php:^8.1" composer require slim/slim:^4.0 slim/psr7 composite/db vlucas/phpdotenv

2.- Configurar la conexión a la base de datos

Composite DB necesita un archivo de configuración para la conexión. Crea src/Config/ConnectionManager.php:

[ 'driver' => 'pdo_sqlite', 'path' => DB_PATH, //SQLite creará este archivo si no existe ], ];

Luego, configura la variable de entorno CONNECTIONS_CONFIG_FILE usando phpdotenv. Crea un archivo .env en la raíz del proyecto:

CONNECTIONS_CONFIG_FILE=../src/Config/ConnectionManager.php

Tip: La ruta ../src/Config/ConnectionManager.php es relativa al directorio public/, desde donde se ejecuta index.php. Esto asegura que Composite DB encuentre el archivo correctamente.

3.- Definir el modelo y la tabla

Crea el enum Status en src/Enums/Status.php:

<?php namespace App\Enums; enum Status: string { case ACTIVE = 'ACTIVE'; case BLOCKED = 'BLOCKED'; }

Usa la entidad User que mostramos antes (src/Model/User.php).

Ahora, define la clase de tabla en src/Model/UsersTable.php:

<?php namespace App\Table; use Composite\DB\AbstractTable; use App\Entity\User; class UsersTable extends \Composite\DB\AbstractTable { protected function getConfig(): \Composite\DB\TableConfig { return \Composite\DB\TableConfig::fromEntitySchema(User::schema()); } /** * @return User[] */ public function findAllActive(): array { return $this->_findAll(['status' => \App\Enums\Status::ACTIVE]); } public function init(): void { $this->getConnection()->executeStatement(" CREATE TABLE IF NOT EXISTS Users ( `id` INTEGER CONSTRAINT Users_pk PRIMARY KEY AUTOINCREMENT, `email` VARCHAR(255) NOT NULL, `name` VARCHAR(255) DEFAULT NULL, `is_test` INT DEFAULT 0 NOT NULL, `status` TEXT DEFAULT 'ACTIVE' NOT NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, CHECK (status IN ('ACTIVE', 'BLOCKED')) ); "); } }

Nota: Llama a init() una vez para crear la tabla. Puedes hacerlo manualmente o en el código inicial (lo veremos más adelante).

4.- Configurar Slim y las rutas

Crea public/index.php con la lógica de la API:

<?php declare(strict_types=1); use App\Controllers\RootController; use App\Controllers\UserController; use DI\ContainerBuilder; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Slim\Factory\AppFactory; use Dotenv\Dotenv; require __DIR__ . '/../vendor/autoload.php'; // Cargar variables de entorno $dotenv = Dotenv::createImmutable(__DIR__ . '/../'); $dotenv->load(); // Configurar PHP-DI $containerBuilder = new ContainerBuilder(); $containerBuilder->addDefinitions([ \App\Table\UsersTable::class => \DI\create(\App\Table\UsersTable::class) ]); // Construir el contenedor $container = $containerBuilder->build(); // Configurar Slim con el contenedor AppFactory::setContainer($container); $app = AppFactory::create(); $app->addRoutingMiddleware(); // Inicializar la base de datos (descomentar solo la primera vez) // $container->get(App\Table\UsersTable::class)->init(); // Rutas $app->get('/', [RootController::class, 'index']); $app->get('/users', [UserController::class, 'list']); $app->post('/users', [UserController::class, 'create']); $app->run();

5.- Probar la API

Crea el directorio database/ en la raíz del proyecto:

mkdir database

Nota: En el repositorio incluyo una base datos SQlite con ejemplos pero si deseas hacerlo desde cero, este es el inicio.

Inicia el servidor de desarrollo:

php -S localhost:8000 -t public

Prueba las rutas:

  • Listar usuarios activos:

curl http://localhost:8000/

Respuesta esperada:

{ "data": [], "message": "Usuarios activos obtenidos correctamente" }

  • Mostrar los usuarios activos:

curl -X GET http://localhost:8000/users

Respuesta esperada:

{ "status": "success", "data": [ { "id": 1, "email": "[email protected]", "name": "John", "is_test": false, "status": "ACTIVE", "created_at": "2025-04-10 22:24:20.128227" }, { "id": 2, "email": "[email protected]", "name": "Martie", "is_test": false, "status": "ACTIVE", "created_at": "2025-04-10 22:56:49.105486" } ], "message": "Usuarios activos obtenidos correctamente" }

  • Crear un usuario:

curl -X POST http://localhost:8000/users -H "Content-Type: application/json" -d '{"email":"[email protected]","name":"Test User"}'

Respuesta esperada:

{ "data": { "id": 1, "email": "[email protected]", "name": "Test User", "is_test": false, "status": "ACTIVE", "created_at": "2025-04-10T20:00:00+00:00" }, "message": "Usuario creado correctamente" }

Limitaciones y cómo sacarle partido

Composite DB no está diseñado para relaciones complejas (como joins automáticos), pero eso no es un obstáculo si sabes adaptarte:

  • Consultas SQL manuales: Usa $usersTable->getConnection()->executeQuery() para consultas personalizadas.
  • Caché opcional: Aunque no lo usamos aquí, Composite DB soporta caché ligero para acelerar consultas recurrentes.
  • Simplicidad como fortaleza: Su enfoque minimalista reduce el overhead y mantiene el código claro.

Por ejemplo, para un join manual:

/** * @return User[] */ public function findAllActiveAdults(): array { return $this->_findAll( new Where( 'age > :age AND status = :status', ['age' => 18, 'status' => Status::ACTIVE->name], ) ); }

Lecciones aprendidas de la documentación

La documentación de Composite DB puede ser confusa:

  • Rutas relativas: No siempre queda claro cómo configurar CONNECTIONS_CONFIG_FILE. Usar phpdotenv y una ruta relativa desde public/ (como ../src/Config/ConnectionManager.php) resuelve el problema.
  • Configuración inicial: Tuve que experimentar para entender cómo el ORM carga el archivo de conexión. Mi consejo: verifica que las rutas sean correctas según tu estructura de carpetas.

Recomendamos usar phpdotenv para una configuración más limpia y asegurarte de que la ruta al archivo de configuración sea correcta según tu estructura de proyecto.

¿Quién está usando Composite DB?

Este ORM está ganando adeptos en:

  • Startups: Ideal para lanzar productos rápidamente.
  • DevOps: Fácil de integrar con herramientas como Prometheus o Grafana.

¿Es Composite DB para ti?

Si valoras:

  • Simplicidad extrema: Configuración mínima, resultados inmediatos.
  • Rendimiento ágil: Como si fuera serverless.
  • PHP moderno: Aprovecha enums, propiedades readonly y atributos.

…¡Entonces es tu herramienta! Si necesitas migraciones complejas o transacciones avanzadas, considera opciones como Doctrine.

Composite DB es una joya para proyectos pequeños, experimentos o cualquier situación donde quieras velocidad y simplicidad. Te dejo el código de ejemplo en este repositorio para que lo explores. ¿Te animas a probarlo en tu próximo proyecto?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.