Services & bootstrap
config/bootstrap.php
This file is your site's extension point. It receives the kernel once per request and once per console run, before config/routes.php, so route handlers can rely on everything registered here:
<?php
declare(strict_types=1);
use TinyTank\Kernel;
return static function (Kernel $app): void {
// Services
$app->container->set(Mailer::class, fn (Kernel $app) => new Mailer(getenv('MAILER_DSN')));
// Twig
$app->twig->addExtension(new App\Twig\AppExtension());
$app->twig->addGlobal('support_email', 'help@example.com');
// Deploy
$app->addDeployStep('audio', 'app:build-audio', 'Encode the sound files');
};The file is optional; delete it if your site doesn't need it.
Services
$app->container is a minimal PSR-11 container:
// A factory: runs once, on first use, receives the kernel; the result is shared.
$app->container->set(Mailer::class, fn (Kernel $app) => new Mailer(getenv('MAILER_DSN')));
// A ready-made value.
$app->container->set('clock', new SystemClock());Use services wherever you have the kernel:
$this->get(Mailer::class) // in a controller
$this->app()->container->get(Mailer::class) // in an AppCommand
$app->container->get('clock') // anywhere else
$app->container->has('clock') // check firstAsking for an unregistered service throws a Psr\Container\NotFoundExceptionInterface.
There's no autowiring and no configuration language: just names and factories. A closure is always treated as a factory, so to store a closure itself, wrap it in a factory.
Twig extensions
Anything Twig supports can be added in bootstrap: extensions, globals, functions, filters.
use Twig\TwigFilter;
$app->twig->addFilter(new TwigFilter('initials', fn (string $name) => implode('', array_map(
fn ($word) => mb_substr($word, 0, 1),
explode(' ', $name),
))));// src/Twig/AppExtension.php
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
final class AppExtension extends AbstractExtension
{
public function getFunctions(): array
{
return [new TwigFunction('year', fn () => date('Y'))];
}
}Other kernel parts
The kernel exposes TinyTank's own services, which you can use (but not replace) from bootstrap: $app->twig, $app->blog, $app->seo, $app->site, $app->router, $app->translations, $app->vite, $app->datastar. See the PHP API reference.