Skip to content

Modelos

Technomantus Corvi edited this page Sep 5, 2026 · 1 revision

Modelos

Cada modelo extiende Model y declara el nombre de su tabla:

<?php

class ArticleModel extends Model
{
    protected static string $table = 'articles';
    protected static bool $timestamps = true; // auto created_at / updated_at
}

Convención de nombres: las clases y archivos de modelos usan el sufijo XxxModel (por ejemplo TodoModel.phpclass TodoModel) para evitar ambigüedad con el nombre de la tabla u otras clases. El autoloader busca el archivo por el nombre exacto de la clase, así que renombrar uno siempre exige renombrar el otro.

API del Model

// ── Lectura ──────────────────────────────────────────────────────────
ArticleModel::all()                        // Todos los registros
ArticleModel::all('title', 'DESC')         // Con orden personalizado
ArticleModel::find(5)                      // Por ID → array | null
ArticleModel::where('active', 1)           // Filtro simple
ArticleModel::where('views', '>', 100)     // Con operador (=, !=, <, >, <=, >=, LIKE)
ArticleModel::first()                      // Primer registro
ArticleModel::count()                      // Total de registros

// Paginación
$result = ArticleModel::paginate(page: 1, perPage: 10);
// $result['data']    → registros de esta página
// $result['total']   → total de registros en la tabla
// $result['pages']   → número total de páginas
// $result['current'] → página actual

// ── Escritura ────────────────────────────────────────────────────────
$id = ArticleModel::create(['title' => 'Hola']);    // → int (ID insertado)
ArticleModel::update(5, ['title' => 'Actualizado']); // → bool
ArticleModel::delete(5);                             // → bool

Si $timestamps = true, create() rellena created_at/updated_at automáticamente, y update() refresca updated_at.

Seguridad de identificadores

Los identificadores de columna y tabla se validan (se rechazan si no cumplen el patrón [a-zA-Z_][a-zA-Z0-9_]*) y se escapan automáticamente según el driver activo — backticks para MySQL, comillas dobles para PostgreSQL y SQLite. Nunca necesitas escaparlos tú mismo, y los nombres de columna dinámicos (por ejemplo, de un input de usuario) se rechazan en vez de interpolarse de forma insegura.

Drivers de base de datos

Pon DB_DRIVER en .env a mysql, pgsql, o sqlite. Para SQLite, define también DB_PATH con la ubicación del archivo .sqlite (se crea automáticamente en la primera escritura si no existe).

DB_DRIVER=mysql   # mysql | pgsql | sqlite
DB_PATH=          # solo se usa cuando DB_DRIVER=sqlite

La conexión es perezosa — si ninguna ruta llama nunca a un modelo, nunca se abre ninguna conexión.

Queries personalizadas más allá de la API base

Para cualquier cosa que la API genérica no cubra, entra directamente a Database::connect() dentro de tu modelo:

class TodoModel extends Model
{
    protected static string $table = 'todo';

    public static function allOrdered(): array
    {
        $table = static::quoteIdent(static::$table);
        $pdo   = Database::connect();
        $stmt  = $pdo->query("SELECT * FROM $table ORDER BY completed ASC, created_at DESC");
        return $stmt->fetchAll();
    }
}

Usa static::quoteIdent() (heredado de Model) para cualquier identificador que interpoles, así tus queries personalizadas se mantienen agnósticas del driver y seguras.

Conexiones opcionales: Redis y MongoDB

Ver Conexiones opcionales.

Clone this wiki locally