Application Lifecycle
Every request in a TrueFramework app follows the same six-step path: front controller → bootstrap → routing → request → handler → render. Understanding the order makes everything else click.
1. Front controller
The web server rewrites every URL to public_html/index.php. That file pulls in the framework's exception classes and then hands off to init.php in the project root:
// public_html/index.php
require '../vendor/truecastdesign/true/src/Exceptions.php';
require '../init.php';
Loading Exceptions.php directly (rather than via Composer's autoloader) means the framework's exception types are available before vendor/autoload.php runs, so any error thrown during bootstrap surfaces with the right exception class.
2. Bootstrap
init.php is where the $App object is built. The shape is:
require 'vendor/autoload.php';
define('BP', __DIR__); // base path
$App = new \True\App;
$App->load('site.ini'); // app/config/site.ini
$App->request = new \True\Request; // wraps $_SERVER, $_GET, $_POST, php://input
$App->response = new \True\Response;
$App->router = new \True\Router($App->request);
$App->view = new \True\PhpView; // .phtml renderer
// Optional — skip if you're not using Hopper
$App->db = new \Truecast\Hopper((array) $App->config->mysql);
require 'app/routes.php';
By the time routes.php runs, $App is fully assembled and configuration is loaded into $App->config as nested objects.
3. Route registration
app/routes.php declares routes by attaching them to $App->router. Routes are registered here, not matched yet:
$App->router->get('/api/users/:id', function($request) use ($App) {
// ...
});
The default scaffold also includes a catch-all at the end that maps every unmatched URL to a controller-by-convention plus a matching .phtml view.
4. Match & dispatch
The router walks registered routes in declaration order and runs the first one whose pattern and HTTP verb match. The handler can be a closure, a path to a controller file, or any callable.
Inside a handler you have access to:
$request— the incoming request object$App— the application (viause ($App)in closures)$request->route->{name}— captured route placeholders
5. Build a response
A handler typically does one of three things:
- Calls
$App->view->render('page.phtml', $vars)to send HTML - Calls
$App->response($data, 'json')to send JSON - Calls
\True\App::go($url)to redirect
6. Output
The view layer wraps your .phtml body in the configured layout (app/views/_layouts/base.phtml by default), interpolates metadata declared at the top of the file (title, description, css, js), and writes the response.
No magic between steps. If something isn't working, you can print_r at any point and see exactly what state $App is in. There's no service container resolution, no compile pass, no cache to invalidate.