# Database Skill ## Purpose Use this skill for PDO, repositories, SQL, migrations, transactions, database configuration, and persistence rules. --- ## Database Stack Preferred database access: - PDO - Repositories or data access classes - Optional SQLite, MySQL, or SQL Server through PDO - Prepared statements for all untrusted values --- ## Database Access Rules Use PDO or a well-maintained database abstraction layer/ORM. Never concatenate untrusted input into SQL. Bad: ```php $sql = "SELECT * FROM users WHERE id = " . $_GET['id']; ``` Good: ```php $stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id'); $stmt->bindValue(':id', $id, PDO::PARAM_INT); $stmt->execute(); $user = $stmt->fetch(PDO::FETCH_ASSOC); ``` Rules: - Use prepared statements and bound parameters. - Validate input before using it in writes. - Keep SQL out of templates. - Keep database access out of controllers where practical. - Use transactions when multiple writes must succeed or fail together. - Do not rely only on client-side validation. - Do not expose raw database errors to users. --- ## Transactions Use transactions when multiple writes must succeed or fail together. Example: ```php $pdo->beginTransaction(); try { $orders->create($order); $auditLog->record('order.created', $order->id()); $pdo->commit(); } catch (Throwable $e) { $pdo->rollBack(); throw $e; } ``` --- ## Repository Rules - Put persistence logic in repositories or data access classes. - Keep repositories focused around a table, aggregate, or use case. - Do not let repositories render HTML. - Do not let repositories read directly from `$_GET`, `$_POST`, or other superglobals. - Return domain objects, entities, DTOs, arrays, or ViewModels according to existing project convention. - Prefer explicit methods such as `findById`, `findAllActive`, and `save` over generic magic calls. --- ## Migration Rules - Keep migrations small and reversible when practical. - Document destructive migrations clearly. - Do not mix schema changes with unrelated feature logic. - Use project migration conventions before inventing new ones. - Support SQLite/MySQL/SQL Server differences explicitly when the project targets multiple engines. --- ## SQL Safety Checklist Before completing database work, verify: - [ ] SQL uses prepared statements or a safe query builder. - [ ] Untrusted values are never concatenated into SQL. - [ ] Writes validate input server-side. - [ ] Multi-step writes use transactions where needed. - [ ] Database errors are logged safely and not displayed raw to users. - [ ] Schema changes are documented. - [ ] Tests or verification steps cover the changed behavior. --- ## Database Configuration - Keep database credentials out of source control. - Prefer environment variables or ignored local config files for secrets. - Provide safe examples such as `.env.example`. - Do not commit production DSNs, passwords, tokens, or private keys. Example `.env.example`: ```text APP_ENV=local APP_DEBUG=true DATABASE_URL=mysql://user:password@localhost:3306/app ```