index - viames/pair GitHub Wiki
Pair framework: index.php
public/index.php is the single entry point of a Pair web application. In most projects it does only two things:
- load Composer
- create the
Applicationsingleton and run it
Minimal bootstrap
<?php
use Pair\Core\Application;
require dirname(__DIR__) . '/vendor/autoload.php';
Application::getInstance()->run();
This remains the minimal bootstrap for Pair v4 applications too; the explicit v4 changes happen inside controllers, responses, and read models.
Pair v4 bootstrap code may also register Runtime Extensions explicitly. Runtime Extensions use RuntimeExtensionInterface and AdapterRegistry for optional adapters, services, UI renderers, routes, or integration configuration. They are separate from Installable Packages, the ZIP/manifest packages used for modules, templates, providers, and custom package records.
Common customizations in index.php
Register guest actions explicitly
Use guestModule() when specific module actions must be accessible without authentication.
Important: in the current Pair code, the access check matches the module plus an explicit allow-list of actions. Pass the actions you want to expose; an empty array is not treated as a wildcard.
$app->guestModule('public', ['status', 'ping']);
$app->guestModule('oauth2', ['login', 'callback', 'refresh']);
Customize API module names
By default, Pair treats api as the API module. You can extend or replace the list:
$app->setApiModules(['api', 'v1', 'webhooks']);
Use a custom user class
If your app extends Pair\Models\User, register it before run():
$app->setUserClass(\App\Models\User::class);
Register runtime extensions and adapters
Use registerRuntimeExtension(...) when an optional integration packages its setup behind RuntimeExtensionInterface:
$app->registerRuntimeExtension(new StripeExtension());
Use setAdapter(...) directly when the bootstrap owns the adapter instance:
$app->setAdapter(\Pair\Core\AdapterKeys::PAYMENTS, $stripeGateway);
Headless mode for CLI or background scripts
For scripts that should execute controller logic without HTML rendering:
use Pair\Core\Application;
Application::getInstance()
->headless()
->run();
Split controller execution from template rendering
Useful for testing, instrumentation, or advanced bootstrap code:
$app = Application::getInstance();
$app->initializeController();
// optional: assign last-minute template variables here
$app->var('buildNumber', '2026.03.26');
$app->renderTemplate();
Extended bootstrap example
<?php
use Pair\Core\Application;
require dirname(__DIR__) . '/vendor/autoload.php';
$app = Application::getInstance();
$app->setUserClass(\App\Models\User::class);
$app->registerRuntimeExtension(new StripeExtension());
$app->guestModule('public', ['status', 'ping']);
$app->guestModule('oauth2', ['login', 'callback']);
$app->setApiModules(['api', 'v1']);
$app->run();
Notes
Application::run()internally callsinitializeController()and thenrenderTemplate().- Environment variables are loaded from
APPLICATION_PATH/.env. - API modules and headless execution skip template rendering.
- Pair v4 actions can return explicit
ResponseInterfaceobjects such asPageResponse,JsonResponse,TextResponse, andEmptyResponse. - Keep
index.phpsmall. Most project-specific behavior belongs in classes, not in bootstrap code.
See also: Application, RuntimeExtensionInterface, AdapterRegistry, Router, Controller, ResponseInterface, API, User.