Controllers are the central building blocks of your application’s logic.
Each controller handles incoming requests, processes data, and determines which views or responses should be returned to the client.
Controllers must extend the Controller class to access all necessary methods and properties.
Controllers can pass data to view files by setting values on the Response object:
<?php
// Example URL: yourdomain.tld/animals/tiger/indo-chinese
class AnimalController extends Controller {
public function index(): void {
$this->response->data["pageTitle"] = "Welcome to Umbrella Corp!";
$this->response->setTitle("Welcome!");
$this->response->setView("welcome-page");
}
}In the above example, the string Welcome to Umbrella Corp! will be available as $pageTitle in the view:
<!-- welcome-page.tpl.php -->
<h1><?php print $pageTitle; ?></h1>A view must be set by each controller using the setView method:
class AnimalController extends Controller {
public function index(): void {
$this->response->setView("animal-index");
}
}The setTitle method is a shortcut for setting a title key in the response data array.
By default, $title is used by the provided header partial in the <title> tag.
Controllers can specify child controllers to be executed after the parent controller:
<?php
class AnimalController extends Controller {
public function index(): void {
$this->children[] = "TigerController";
}
}In this example, TigerController will be invoked after AnimalController.
Only the index method is called on child controllers.
Response data set by a parent controller is accessible and modifiable by its children.
Controllers can throw StatusCode exceptions to reroute the request stack to a different status code controller.
The following exceptions are available:
| Exception | HTTP Code | Use Case |
|---|---|---|
\Core\StatusCode\BadRequest |
400 | Malformed or invalid request data |
\Core\StatusCode\Unauthorized |
401 | Authentication required |
\Core\StatusCode\Forbidden |
403 | Access denied for authenticated users |
\Core\StatusCode\NotFound |
404 | Resource or path does not exist |
\Core\StatusCode\NotAcceptable |
406 | Request format not supported |
Example:
<?php
class UserController extends \Controller {
public function profile(): void {
// Check if user is authenticated
if (!$this->isAuthenticated()) {
throw new \Core\StatusCode\Unauthorized();
}
// Check if user has permission
if (!$this->hasPermission("view_profile")) {
throw new \Core\StatusCode\Forbidden();
}
// Validate input
if (empty($_GET["id"])) {
throw new \Core\StatusCode\BadRequest();
}
// Continue with normal processing
$this->response->setView("user/profile");
}
}When a StatusCode exception is thrown, the framework automatically routes the request to the corresponding status code controller (e.g., UnauthorizedController, ForbiddenController, etc.).
Note
Namespaced controllers are not routeable.
Meaning they will become inaccessible by URL and CLI.
Controllers can be namespaced for partials and complex structures.
For example, you can use namespaces like Partial or StatusCode:
<?php
class PageController extends Controller {
public function index(): void {
// Add partials as child controllers
$this->children[] = new ClassName("Partial\Alerts");
$this->children[] = new ClassName("Partial\Sidenav");
}
}Example namespaced controllers:
<?php
namespace Partial;
class AlertsController extends \Controller {
public function index(): void {
$view = $this->template->getViewPath("partials/alerts");
$this->response->data["alerts"] = $view;
}
}<?php
namespace Partial;
class SidenavController extends \Controller {
public function index(): void {
$view = $this->template->getViewPath("partials/sidenav");
$this->response->data["sidenav"] = $view;
}
}This assumes you have view files like alerts.tpl.php in a partials folder.
See Template and theming for more details.
Controllers extending the base Controller class inherit several pre-wired properties for routing, templating, content negotiation, and more.
These are set automatically and should not be manually overwritten.
- Type:
null|\Controller - Description: Reference to the parent controller, if any.
- Usage Example:
if ($this->parent instanceof \AuthController) { /* ... */ } if ($this->parent === null) { /* top-level controller */ }
- Type:
\Core\Request - Description: Represents the current HTTP request (GET, POST, files, cookies, etc.).
- Usage Example:
$this->request->get; $this->request->post; $this->request->files; $this->request->cookies; $this->request->server;
- Type:
\Core\Response - Description: Handles output data and headers.
- Usage Example:
$this->response->data['title'] = 'My Page'; $this->response->setStatusCode(404);
- Type:
\Core\Application - Description: The root application instance.
- Usage Example:
$this->application->getExecutedClassName(); $this->application->getCalledMethodName();
- Type:
\Core\Router - Description: Manages routing state and request/response resolution.
- Usage Example:
$path = $this->router->getRoute();
- Type:
\Core\Template - Description: Handles asset injection and layout template resolution.
- Usage Example:
$view = $this->template->getViewPath("partial/sidenav"); $path = $this->template->getDirectoryUri("assets/img/logo.png");
- Type:
\Core\Assets - Description: Manages asset registration and injection (CSS, JS, images).
- Usage Example:
$this->assets->addStylesheet("assets/css/styles.css"); $this->assets->addJavascript("assets/js/app.js");
- Type:
\Core\ContentType\ContentTypeInterface - Description: Holds the negotiated content type (HTML, JSON, XML, etc.).
- Usage Example:
if ($this->contentType::class === \Core\ContentType\Html::class) { // Render HTML }
- Type:
\Core\Renderer - Description: Combines response data, template, and content type into output.
- Usage Example:
$this->renderer->render($this->response);
- Type:
array - Description: List of child controllers to execute after the main one (used for layouts/partials).
- Usage Example:
$this->children[] = new ClassName('Partial\\Sidebar');
While the above properties are protected and can be access by inheritance, they each have a corresponding getX() method:
getRequest()→$requestgetResponse()→$responsegetApplication()→$applicationgetRouter()→$routergetTemplate()→$templategetChildren()→$childrengetParent()→$parent