Helpers Reference
Last updated: 04/17/2026 · Written by Agent0
Helpers Reference
StackCTL provides a set of global helper functions that are available everywhere in your application — controllers, views, and anywhere else. They're loaded automatically during bootstrap via Composer's autoloader, so no imports or use statements are needed.
This page is a complete reference for every helper. For deeper usage context, see the linked docs for each section.
Config
config()
Retrieve a value from the config files using dot notation. Returns null if the key doesn't exist.
config('app.name') // → 'StackCTL'
config('app.env') // → 'local'
config('database.host') // → 'localhost'
config('auth.remember_me') // → false
The first segment is the config filename, the rest are keys within that file. See the Configuration doc for all available keys.
Output & Escaping
e()
Escape a value for safe HTML output. Always use this when rendering user-supplied data in views to prevent XSS attacks.
<?= e($article->title) ?>
<?= e($user->name) ?>
<?= e(auth('email')) ?>
Returns an empty string safely if null is passed. Skip it only when you intentionally want to render raw HTML that has already been sanitized.
Routing
redirect()
Redirect the user to a URL and stop execution. Always call this after a form submission — never render a view directly after a POST.
redirect('/dashboard');
redirect('/login');
redirect('/articles/' . $id);
redirect_back()
Redirect to the previous page using the HTTP referrer. Accepts an optional fallback URL if no referrer is available.
redirect_back(); // falls back to '/'
redirect_back('/articles'); // falls back to /articles
Most commonly used after a failed validation — redirect back to the form so the user can correct their input.
abort()
Stop execution and render the matching error page. Sets the correct HTTP status code and renders the corresponding view from resources/views/errors/.
abort(404); // Not Found abort(403); // Forbidden abort(500); // Internal Server Error
// Common pattern — 404 if a record isn't found
$article = Query::table('articles')->find((int)$id);
if (!$article) {
abort(404);
}
route()
Get the URL for a named route. Named routes are defined with ->name() in routes/web.php. Use this instead of hardcoding URLs — if a URI changes, you only update it in one place.
// In web.php:
$router->get('/dashboard', 'DashboardController@index')->name('dashboard');
$router->get('/articles/{id}', 'ArticlesController@show')->name('articles.show');
// Anywhere in your app:
route('dashboard') // → '/dashboard'
route('articles.show', [$article->id]) // → '/articles/5'
Flash Messaging
flash()
Store a flash message that survives exactly one redirect, then is cleared. Flash messages are displayed automatically as toast notifications by the base layout.
flash('success', 'Article saved successfully.');
flash('error', 'Something went wrong.');
flash('info', 'Please verify your email address.');
Always call flash() before a redirect() — the message is carried over to the next page and then removed.
get_flash()
Retrieve a specific flash value by key, then clear it from the session. Used internally by the form helpers — you'll rarely need to call this directly.
$value = get_flash('errors');
get_flash_all()
Retrieve all flash notifications (excluding form errors) and clear them. Called automatically by the base layout to render toast messages — you won't need to call this directly in most cases.
$flashes = get_flash_all(); // Returns: [['type' => 'success', 'message' => '...'], ...]
Form Handling
old()
Retrieve a previously submitted form value from the session. Use this to repopulate form fields after a failed validation so users don't have to retype everything.
<input type="text" name="title" value="<?= e(old('title')) ?>">
// With a fallback for edit forms
<input type="text" name="title" value="<?= e($article ? $article->title : old('title')) ?>">
errors()
Retrieve all validation errors from the flash store. Call this once at the top of a form, then pass the result to error() and has_error() per field. Cached statically so the session is only read once per request.
<?php $errors = errors(); ?>
error()
Render the first validation error message for a specific field as an HTML element. Returns an empty string if no error exists — always safe to echo without a conditional.
<?= error($errors, 'email') ?> <?= error($errors, 'password') ?>
has_error()
Returns the input-error CSS class string if a field has a validation error, otherwise an empty string. Applies the red border styling defined in theme.css.
<input class="input <?= has_error($errors, 'email') ?>" name="email">
csrf_field()
Render a hidden CSRF token input field. Include this inside every POST form — StackCTL verifies the token automatically on every POST request and aborts with 419 if it's missing or invalid.
<form method="POST" action="/articles/save">
<?= csrf_field() ?>
...
</form>
csrf_token()
Returns the raw CSRF token string for the current session. Use this when you need the token value directly — for example, in an AJAX request header rather than a hidden form field.
$token = csrf_token();
// Example: passing to a JS variable for AJAX use
<script>
const csrfToken = '<?= csrf_token() ?>';
</script>
Authentication
For full usage details and middleware examples, see the Auth & Middleware doc.
is_auth()
Returns true if the current user is logged in.
if (is_auth()) {
// user is logged in
}
// In a view
<?php if (is_auth()): ?>
<a href="/dashboard">Dashboard</a>
<?php endif; ?>
auth()
Returns the current user's session data. Pass a field name to get a specific value. Use for quick access to session-stored values — for database-fresh data, use user() instead.
auth() // full session array, or null if not logged in
auth('name') // display name
auth('email') // email address
auth('role') // role string
auth('last_login') // last login timestamp
user()
Returns the current user's full database record. Runs one query on first call, then caches the result for the rest of the request. Use this when you need accurate, up-to-date field values that may not be stored in the session.
user() // full database object, or null
user('email') // specific column value
user('is_subscribed') // any column from the users table
has_role()
Check if the current user has a specific role. Pass a string for a single check or an array to check if the user has any of the listed roles.
has_role('admin')
has_role(['admin', 'developer', 'editor'])
can()
Check if the current user is permitted to perform an action on a resource. Uses the permissions map defined in config/auth.php. Returns false if the user is not logged in.
can('edit', 'article') // can this user edit articles?
can('delete', 'article') // can this user delete articles?
can('manage', 'user') // can this user manage users?
// In a view
<?php if (can('edit', 'article')): ?>
<a href="/articles/form/<?= $article->id ?>">Edit</a>
<?php endif; ?>
UI Utilities
initials()
Generate up to two uppercase initials from a full name. Used as a text-based avatar fallback when no profile image exists.
initials('John Doe') // → 'JD'
initials('Mary Ann Smith') // → 'MA'
initials('Chris') // → 'C'
// In a view
<div class="avatar"><?= initials(auth('name')) ?></div>
is_active()
Returns a CSS class string to highlight the current navigation link. Pass true (default) for an exact URI match, or false for a prefix match that also highlights on sub-pages.
<a href="/articles" class="nav-link <?= is_active('/articles') ?>">
Articles
</a>
<!-- Prefix match — active on /articles and /articles/form/5 etc. -->
<a href="/articles" class="nav-link <?= is_active('/articles', false) ?>">
Articles
</a>
paginate()
Render HTML pagination links for a result set returned by Query::paginate(). Returns an empty string if there's only one page, so it's always safe to echo.
// In a view, after looping through $results->data: <?= paginate($results) ?> // With extra CSS classes on the wrapper <?= paginate($results, 'mt-6 justify-end') ?>
See the Query doc for full pagination usage including the controller side.
Database Utilities
generate_slug()
Convert a string to a unique, URL-safe slug, checking the specified database table to guarantee uniqueness. Appends an incrementing suffix (-1, -2…) if the base slug is already taken.
$slug = generate_slug('Hello World', 'articles');
// → 'hello-world' (or 'hello-world-1' if already taken)
// Custom column name
$slug = generate_slug($name, 'categories', 'url_key');
Only call this on create, not on update — regenerating a slug on update breaks existing links. See the Slug Generator doc for full details.