Controllers live in lf-app/Controller/, namespace App\Controller. A controller is a plain class — there’s no base class to extend.
php laika controller:make UserController --method=index
namespace App\Controller;
use App\Model\UsersModel;
use Laika\Engine\App\Template;
class UserController
{
public function show(string $id): string
{
$user = (new UsersModel())->find($id);
$tpl = new Template();
$tpl->assign('user', $user);
return $tpl->view('users/show'); // template/users/show.twig
}
}
// lf-routes/web.php
Url::get('/users/{id}', 'UserController@show')->name('users.show');
A controller method must return a string or null. Whatever it returns is passed through the filters and then sent.
| Return | Result |
|---|---|
string |
Sent, rendered according to the response content type (HTML by default) |
null / '' |
Nothing is sent — not even headers or a status set on Response |
| array, int, object | TypeError |
Returning JSON, setting a status, redirecting and downloading files are all covered in Responses:
use Laika\Engine\Services\Response;
public function status(): string
{
Response::setContentType('application/json');
return json_encode(['status' => 'ok']);
}
A bare
json_encode()withoutsetContentType()is sent astext/html. And a barehttp_response_code(404)is overwritten when the response is sent — useResponse::setStatus(404).
Parameters are passed by name, so the order of your method’s arguments doesn’t matter:
// Url::get('/posts/{year}/{slug}', 'PostController@show');
public function show(string $slug, string $year): string { /* ... */ }
Route values are always strings, and the router runs under strict_types, so int $id throws a TypeError. Type them string (or leave them untyped) and cast:
public function show(string $id): string
{
$user = (new UsersModel())->find((int) $id);
// ...
}
Pipeline args ('Role|role=admin') and anything a pipeline writes into $params are passed the same way, and override a route parameter of the same name. Filter args never reach the controller.
Controllers are built through the service container, so both the constructor and method parameters can ask for services by type:
namespace App\Controller;
use Laika\Engine\Auth\AuthManager;
use App\Service\Billing;
class InvoiceController
{
public function __construct(private AuthManager $auth) {}
public function show(string $id, Billing $billing): string
{
$user = $this->auth->guard('web')->user();
// ...
}
}
How each method parameter is filled, in order:
null, if the parameter is nullable.RuntimeException (“Missing required parameter”).Don’t type-hint relays or core classes. The framework’s own services are bound under keys (
'response','request', …), not class names. Type-hintingLaika\Engine\Http\Responsebuilds a newResponse— setting its status changes nothing. Type-hinting a relay (Laika\Engine\Services\Request) gives you a proxy object whose instance methods don’t exist. Call relays statically instead:Request::input('email'),Response::setStatus(201).
use Laika\Engine\App\Template;
public function index(): string
{
$tpl = new Template();
$tpl->assign(['title' => 'Home', 'welcome' => 'Welcome to Laika!']);
return $tpl->view('home'); // template/home.twig
}
See Templates.
use Laika\Engine\Services\{Request, Redirect};
public function store(): ?string
{
if (!Request::validate(['email' => 'required|email', 'name' => 'required|max:100'])) {
return $this->create(); // the form again; the template gets the `errors` variable
}
(new UsersModel())->insert(Request::only(['email', 'name']));
Redirect::with('User created.', true)->to('users.index'); // exits
}
See Requests for input, files, headers and validation.
use App\Model\UsersModel;
$user = (new UsersModel())->where(['id' => $id])->firstOrFail();
See Models & Database.
use Laika\Engine\Session\Session;
$userId = Session::get('user_id');
A session driver must be configured first — see Sessions.
Pipelines run before the controller and filters run after it — see Pipelines and Filters.
| Command | Description |
|---|---|
php laika controller:make <name> [--method=index] |
Create a controller, or add a method to an existing one |
php laika controller:list |
List controller classes |
php laika controller:remove <name> |
Delete a controller |
php laika controller:rename --old=<name> --new=<name> |
Rename a controller class and its file |