| Home | Getting Started | Core Concepts | Helpers | Extensions | Repo |
Controllers receive a TinyRequest and a TinyResponse on every invocation. Both are also accessible globally via tiny::request() and tiny::response() — useful from middleware and components.
TinyRequest$request->method; // "GET" | "POST" | …
$request->headers; // associative array (output of getallheaders())
$request->htmx; // bool: true when HX-Request header is present
$request->user; // object set by middleware via tiny::user($user)
$request->query; // $_GET
$request->path; // object: { controller, section, slug, full }
$request->csrf_token; // populated after body() is called
path$request->path->controller; // "users" (first URL segment)
$request->path->section; // "profile" (second URL segment, or "")
$request->path->slug; // "edit" (everything after, or "")
$request->path->full; // "/users/profile/edit"
params(?string $key = null, mixed $fallback = null)Case-insensitive lookups over the merged $_REQUEST (GET + POST + cookies):
$all = $request->params();
$email = $request->params('email');
$page = $request->params('page', 1);
body(bool $associative = false)Returns the parsed request body (handles JSON, form-encoded, and $_POST). Pass true for an associative array; default is stdClass.
$body = $request->body(); // stdClass
$body = $request->body(true); // array
The CSRF token is extracted from body() automatically and stripped from the returned value.
json()Returns the raw php://input string. Useful for webhook signature verification:
$raw = $request->json();
$signature = $request->headers['Stripe-Signature'];
tiny::stripe()->verifyWebhook($raw, $signature);
isValidCSRF(bool $remove = true): boolValidates the CSRF token in the body. Returns true if valid, false otherwise. By default the token is consumed after validation.
if (!$request->isValidCSRF()) {
return $response->hasCSRFError();
}
isAsync(): boolReturns true if any of these is true:
X-Requested-With: AsyncRequest header?async=true in query stringUse it to short-circuit rendering of large templates.
TinyResponseAll $response methods that “send” a response terminate the request by default. Pass $die = false to keep the script running.
render(string $file = '', array $params = [], bool $die = true): voidRenders a view file from app/views/. $params are merged into tiny::data(). Automatically emits HX-Push-Url matching the current permalink (HTMX-friendly).
$response->render('users/index');
$response->render('users/show', ['user' => $user]);
$response->render('users/show', ['user' => $user], false); // don't exit
renderReact(string $component, array $props, array $meta = [], ?string $template = null): voidRenders a React component. Two modes:
$template view with the component name and props embedded.X-SPA-Request: true or is XHR, returns JSON {component, props} for client-side routing.$response->renderReact('DashboardPage', [
'user' => tiny::user(),
'stats' => $stats,
], meta: ['title' => 'Dashboard'], template: 'react-shell');
redirect(?string $goto = null, ?string $header = null): voidHTMX-aware redirect. If the current request is HTMX, emits HX-Redirect; otherwise sends a 302.
$response->redirect('/login');
$response->redirect('/login', 'htmx'); // force HX-Redirect
$response->redirect('/users', 301); // permanent redirect
The $header parameter accepts 301, 302, 'javascript', 'htmx', or 'csrf'.
send(mixed $payload, int $code = 200, bool $die = true): voidJSON-encodes the payload and sends it with the given status code (no content-type header — that’s sendJSON’s job).
$response->send(['status' => 'ok']);
$response->send($obj, 201);
sendJSON(mixed $data, int $code = 200, bool $die = true): voidSets Content-Type: application/json and emits a JSON response.
$response->sendJSON(['users' => $users]);
$response->sendJSON(['error' => 'Bad input'], 422);
sendFile(string $path, int $code = 200, bool $die = true): voidStreams a file’s contents as the response body.
$response->sendFile('/srv/reports/q4.pdf');
flush(string $string = '', bool $finish_request = true): voidFlush partial content. Useful for long-running tasks where you want to send some output before the script finishes (e.g. ahead-of-time HTML hints).
$response->flush('<!doctype html>…');
expensiveBackgroundWork();
hasCSRFError(string $id = 'CSRF-VALIDATION-FAILED', bool $nextPage = false): voidDisplay a CSRF error. Pass $nextPage = true to defer the error to the next page load (uses flash messaging).
if (!$request->isValidCSRF()) {
return $response->hasCSRFError();
}
When you don’t have a controller method’s $request / $response in scope (e.g. from middleware, helpers, components), use the singletons:
tiny::request()->headers['User-Agent'];
tiny::response()->sendJSON(['ok' => true]);
These return the same instances passed to the controller.
$request->path is populated