Bootstrap & Lifecycle

How the application boots for HTTP, CLI, and tests, and when services are made available.

Category: Core Architecture

VelvetCMS uses a single bootstrap file for every entrypoint. Understanding that flow makes debugging effortless.

1. Entry points #

Context File Responsibilities
HTTP public/index.php Load Composer autoloader, bootstrap the app, boot it, capture the request, and dispatch routes (with caching fallback).
CLI velvet Locate vendor autoloaders, bootstrap the app if possible, set up CommandRegistry, register commands, then parse/execute argv.
Tests tests/bootstrap.php (not shown above) Requires the same bootstrap/app.php so unit/integration tests resolve the real container.

2. bootstrap/app.php #

$app = new Application(VELVET_BASE_PATH);
App::setInstance($app);
$app->alias('events', EventDispatcher::class);
$app->alias('router', Router::class);
$app->alias('db', Connection::class);
$app->alias('cache', CacheDriver::class);
  • Defines VELVET_BASE_PATH if unset.
  • Instantiates VelvetCMS\Core\Application, which immediately loads .env and registers core services.
  • Stores the container inside the App facade so helper functions can resolve dependencies even before HTTP boot.

3. Boot sequence #

Application::boot() runs for HTTP requests:

  1. Sets timezone (config('app.timezone', 'UTC')).
  2. Configures secure PHP session INI values and starts the session (only outside CLI).
  3. Fires app.booting and app.booted events via EventDispatcher so modules or services can hook in.

4. Container internals #

Need to dive deeper into bindings, aliases, and autowiring? Jump to Service Container. All you have to remember here is that the bootstrap registers singletons (config, events, router, DB, cache, pages, theme, modules) and app()/helper calls are just facades over those bindings.

5. Environment + config loading #

Application::loadEnvironment() parses .env, exports values into $_ENV, $_SERVER, and putenv(). Config files are lazily loaded via ConfigRepository, which caches arrays and can write a compiled copy to storage/cache/config.php (used by config:cache).

6. Module lifecycle #

The high-level sequence is still load → register → boot, but the nitty gritty (discovery paths, manifests, CLI tooling, events) now lives in Events & Modules and the Modules chapters. Refer to those when you need dependency graphs or CLI walkthroughs.

7. HTTP request flow #

  1. Request::capture() snapshots $_GET, $_POST, etc.
  2. Router loads cached definitions if storage/cache/routes.php exists; otherwise routes/web.php closure runs, registering routes.
  3. Router::dispatch() finds the best match, builds a middleware pipeline with global + route-specific middleware, and executes the handler.
  4. Exceptions bubble to ExceptionHandlerInterface (resolved to VelvetCMS\Exceptions\Handler), which reports/logs and renders a response (or rethrows in debug mode).

The CLI flow mirrors this, minus HTTP-only steps. By sharing the bootstrap, modules and services behave consistently everywhere.