-
Notifications
You must be signed in to change notification settings - Fork 0
Controllers and Requests
Technomantus Corvi edited this page Sep 5, 2026
·
1 revision
Every controller extends Controller and gets access to $this->request, plus a set of response helpers.
<?php
class ArticleController extends Controller
{
public function index(): void
{
$this->view('article/index', [
'title' => 'Articles',
'articles' => ArticleModel::all(),
]);
}
public function store(): void
{
$title = $this->request->post('title');
if (empty($title)) {
$this->flash('error', 'Title is required.');
$this->redirect('/article/create');
}
ArticleModel::create(['title' => $title]);
$this->flash('success', 'Article created.');
$this->redirect('/article');
}
}| Method | Description |
|---|---|
$this->view($name, $data) |
Renders a view inside the layout |
$this->redirect($path) |
Redirects and stops execution |
$this->json($data, $status) |
Returns JSON and stops execution |
$this->abort404() |
Shows the 404 page and stops execution |
$this->flash($key, $message) |
Stores a flash message in the session |
$this->request |
The current Request instance |
public function dashboard(): void
{
auth_require(); // redirects to /login if not authenticated
$user = auth_user();
$this->view('dashboard/index', ['user' => $user]);
}See Authentication for the full auth helper reference.
$this->request->post('field') // Value from $_POST
$this->request->get('param') // Value from $_GET
$this->request->input('field') // POST first, falls back to GET
$this->request->all() // All inputs merged (POST wins)
$this->request->only(['a', 'b']) // Only those fields
$this->request->except(['token']) // All fields except those
$this->request->has('field') // bool: exists and not empty?
$this->request->file('avatar') // $_FILES entry, or null
$this->request->method() // 'GET', 'POST', 'PUT'…
$this->request->isGet() / isPost() / isPut() / isDelete()
$this->request->isAjax() // bool
$this->request->ip() // Client IP — see note below
$this->request->uri() // Current path, no query stringRequest::ip() trusts the X-Forwarded-For header, which any client can set — only rely on it behind a trusted reverse proxy that overwrites that header. See Security.
public function store(): void
{
$title = $this->request->post('title');
$description = $this->request->post('description', '');
if (empty($title)) {
keep_old(['title' => $title, 'description' => $description]);
$this->flash('error', 'Title is required.');
$this->redirect('/article/create');
}
// ...
}In the view:
<input type="text" name="title" value="<?= e(old('title')) ?>">keep_old() stores the data in the session; old() retrieves it once and view() clears it automatically after rendering, so it only survives a single redirect-and-redisplay cycle.
public function store(): void
{
if (!csrf_verify($this->request->post('_token'))) {
$this->flash('error', 'Your session expired. Please try again.');
$this->redirect('/article/create');
}
// ...
}In the view:
<form method="POST" action="/article">
<?= csrf_field() ?>
<!-- ... -->
</form>Not enforced globally by the router on purpose — see Security for why.