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 Application singleton 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 calls initializeController() and then renderTemplate().
  • Environment variables are loaded from APPLICATION_PATH/.env.
  • API modules and headless execution skip template rendering.
  • Pair v4 actions can return explicit ResponseInterface objects such as PageResponse, JsonResponse, TextResponse, and EmptyResponse.
  • Keep index.php small. Most project-specific behavior belongs in classes, not in bootstrap code.

See also: Application, RuntimeExtensionInterface, AdapterRegistry, Router, Controller, ResponseInterface, API, User.