-
Notifications
You must be signed in to change notification settings - Fork 0
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 ejemploTodoModel.php→class 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.
// ── 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); // → boolSi
$timestamps = true,create()rellenacreated_at/updated_atautomáticamente, yupdate()refrescaupdated_at.
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.
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=sqliteLa conexión es perezosa — si ninguna ruta llama nunca a un modelo, nunca se abre ninguna conexión.
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.