Overview
The CFB Marble Game is built as a modern PHP application using:- PHP 8.4 with strict typing and modern language features
- Dependency Injection via PHP-DI for service management
- FastRoute for HTTP routing
- Sapien for request/response handling
- SQLite for data persistence
- Monolog for logging
Application Bootstrap
The application initializes through a two-stage bootstrap process:Bootstrap.php
TheBootstrap class handles application initialization:
Bootstrap.php:14-38
- Initialize the dependency injection container
- Configure error handling (Whoops for development, Monolog for production)
- Return configured container for service resolution
Container.php
TheContainer class configures all service definitions:
Container.php:35-43
- Autowiring enabled for automatic dependency resolution
- Explicit definitions for complex services
- Secret management via environment variables or Docker secrets
Dependency Injection
The application uses PHP-DI with explicit service definitions for core components:Core Service Definitions
Repository Pattern
The application implements the Repository pattern with decorator support:- Interfaces define contracts (
TeamRepository,GameRepository) - SQLite implementations provide data access
- Cached decorators wrap repositories for performance (e.g.,
CachedTeamRepository)
HTTP Request Flow
1. Front Controller
TheFrontController orchestrates the request/response cycle:
FrontController.php:18-24
2. Request Handler
TheRequestHandler manages routing and action invocation:
RequestHandler.php:34-72
- FastRoute dispatching with method and path resolution
- Automatic dependency injection for route handlers
- Type-safe response validation
3. Route Definition
Routes are defined in theRoutes class:
Routes.php:16-26
- Must be callable (implement
__invoke) - Must return
Sapien\Response - Can type-hint dependencies in constructor or
__invokemethod
Templating
The application uses native PHP templates:- Templates are
.html.phpfiles - Located alongside their corresponding action classes
- Rendered using simple
includewith variable extraction - No complex templating engine required
Dependencies
Fromcomposer.json:
Architecture Principles
Domain-Driven Design
- Domain logic isolated in
App\Rankingsnamespace - Clear separation between domain models and infrastructure
- Value objects for type safety (
TeamId,GameId,Conference,Subdivision)
SOLID Principles
- Single Responsibility: Each class has one clear purpose
- Dependency Inversion: Depend on interfaces, not concrete implementations
- Interface Segregation: Small, focused interfaces (e.g.,
TeamRepository)
Immutability
- Extensive use of
readonlyclasses and properties - Value objects are immutable
- Domain events (marble transfers) modify mutable state on
Teamobjects
Error Handling
Development Mode
- Whoops error handler with pretty HTML/JSON error pages
- Activated via
DEBUG_MODEenvironment variable - Content-type aware (HTML vs JSON)
Production Mode
- Monolog error handler
- Logs to stdout (container-friendly)
- Configurable log level via
LOG_LEVELenvironment variable - Web processor adds request context to log entries
Configuration
Configuration is managed through environment variables:DB_PATH- Path to SQLite database fileLOG_LEVEL- Monolog log level (defaults to Notice)DEBUG_MODE- Enable Whoops error handlerCFBD_API_KEY- CollegeFootballData.com API key (via env or Docker secret)
Secret Management
The application supports two methods for secret storage:Container.php:99-120
- Environment variables (for local development)
- Docker secrets (for production deployment)