Controllers
Controllers are responsible for handling incoming HTTP requests and returning responses to the client. They act as the bridge between the router, business logic, and the presentation layer. In SigmaPHP, controllers help keep your application organized by grouping related actions into a single class.
Creating a Controller
Creating a new controller is straightforward using the CLI utility:
./bin/sigma-cli create:controller HelloController
This command generates a new controller class inside your application's controllers directory, following the framework’s default structure and namespace conventions.
<?php
namespace App\Controllers;
use SigmaPHP\Core\Controllers\BaseController;
class HelloController extends BaseController
{
/**
* Welcome page.
*
* @param string $name
* @return Response
*/
public function welcome($name = 'anonymous')
{
return $this->render('app', [
'name' => $name,
]);
}
}
This action can then be linked to a route as shown below:
<?php
return [
[
'name' => 'welcome',
'path' => '/welcome/{name?}',
'method' => 'get',
'controller' => HelloController::class,
'action' => 'welcome',
],
];
An Action inside a controller represents the method that is executed when a route is matched. It is responsible for handling the incoming request, performing the required business logic, and returning a response back to the client.
The term “action” is simply a naming convention used to describe controller methods that are exposed to the router.
Request
The Request object represents the current HTTP request and provides a clean,
structured way to access incoming data. Instead of interacting directly with
PHP super globals such as $_GET, $_POST, or
$_FILES, SigmaPHP exposes a unified interface that keeps your
controller logic consistent and easier to maintain. The Request instance can
be injected directly into controller actions through dependency injection.
use SigmaPHP\Core\Http\Request;
public function example(Request $request)
{
/*
|------------------------------------------------------------
| Reading Input Data
|------------------------------------------------------------
*/
$page = $request->get('page');
// Example URL: /products?page=2
// Result: 2
$email = $request->post('email');
// Example POST body: email=test@example.com
// Result: "test@example.com"
$avatar = $request->files('avatar');
// Example uploaded file input name="avatar"
// Result: Uploaded file information array/object
/*
|------------------------------------------------------------
| Request Information
|------------------------------------------------------------
*/
$currentUrl = $request->current();
// Result: "http://localhost/products?page=2"
$previousUrl = $request->previous();
// Result: "http://localhost/home"
$method = $request->method();
// Result: "GET" or "POST" or "PUT" ...
$port = $request->port();
// Result: "80" or "443"
$secure = $request->isSecure();
// Result: true (HTTPS) or false (HTTP)
/*
|------------------------------------------------------------
| Headers
|------------------------------------------------------------
*/
$headers = $request->headers();
// Result example:
// [
// 'host' => 'localhost',
// 'user-agent' => 'Mozilla/5.0',
// 'accept' => 'text/html'
// ]
/*
|------------------------------------------------------------
| Checking Data Existence
|------------------------------------------------------------
*/
$hasPage = $request->has('page');
// Result: true if exists in GET, POST, or FILES
$hasAvatar = $request->has('avatar');
// Result: true if file was uploaded
/*
|------------------------------------------------------------
| Typical Usage Example
|------------------------------------------------------------
*/
if (!$request->has('email')) {
return $this->redirect('/register');
}
return $this->json([
'page' => $page,
'email' => $email,
'secure' => $secure
]);
}
Response
The response methods allow an action to return content to the client in a controlled and standardized way.
The response($data, $type, $code, $headers) method creates a custom HTTP response where you can
define the body, content type, status code, and headers. For API-style responses,
json($data, $code, $headers) automatically formats the output as JSON and sets the appropriate
response headers.
public function show()
{
return $this->response(
'Hello from SigmaPHP
',
'text/html',
200,
['X-App' => 'SigmaPHP']
);
}
public function api()
{
return $this->json(
['status' => 'success', 'message' => 'Data loaded'],
200,
['X-API-Version' => '1.0']
);
}
Rendering Views
Rendering methods simplify returning HTML content from templates. The
render($templateName, $variables, $code, $headers) method renders a view and immediately returns
it wrapped inside an HTTP response. When you only need the generated HTML as a string, for example to compose
partial content, renderView($templateName, $variables) can be used instead.
public function dashboard()
{
return $this->render(
'dashboard',
['title' => 'Admin Panel', 'user' => 'Mohamed'],
200,
['Cache-Control' => 'no-cache']
);
}
public function partial()
{
$content = $this->renderView(
'partials.stats',
['visits' => 1500, 'sales' => 230]
);
return $this->response($content);
}
Redirecting
Redirect methods provide a convenient way to navigate users between pages after completing an action.
The redirect($url) method sends the user to a specific URL, while
route($routeName, $parameters) generates a URL based on a named route before redirecting.
Additionally, back() returns the user to the previous page, which is especially useful after
form submissions or validation workflows.
public function store()
{
// ... save data
return $this->redirect('/users/profile');
}
public function update()
{
// ... update logic
return $this->route(
'users.profile',
['id' => 5]
);
}
public function cancel()
{
return $this->back();
}
Abort Execution
In certain scenarios, it is necessary to immediately terminate the execution flow within a controller and return an appropriate error response. This can be useful for handling invalid states, unauthorized access, or unexpected conditions.
The framework provides a dedicated error method to simplify this process. When invoked, it stops further execution and triggers the appropriate error handling mechanism, such as rendering an error page or returning a JSON response.
Call the error method from within your controller whenever you need to halt execution and return a specific HTTP error code.
For example, you might use it when a requested resource is not found or when access is denied.
public function show($id)
{
if (!$this->userCanAccessResource($id)) {
$this->error(401);
}
...
}
Base Controller
All controllers extend the Base Controller, which acts as the foundation for handling HTTP interactions inside
your application. It provides essential functionality required by most actions, including creating responses,
rendering views, and performing redirects. By centralizing these common operations, controllers remain clean,
focused, and easy to maintain while avoiding repetitive boilerplate code. Every action can directly access these
features using $this->, allowing developers to work with requests and responses in a consistent
and expressive way.
/**
* Post data
*
* @param Request $request
* @return Response
*/
public function postData(Request $request)
{
if ($request->method() == 'POST') {
if ($request->post('value') > 100) {
$this->flash('error', 'Invalid Value');
$this->saveOldValues();
return $this->back();
} else {
$this->flash('success', 'Done');
return $this->route('index');
}
}
return $this->render('form');
}
Single Action Controller
Single Action Controllers are also supported. These controllers are useful when a controller is responsible for only one task, improving readability and reducing unnecessary method definitions.
When no action is provided, the router automatically executes
the __invoke() method, allowing the controller itself to behave
like a callable action.
<?php
namespace App\Controllers;
use SigmaPHP\Core\Controllers\BaseController;
class NotificationController extends BaseController
{
public function __invoke()
{
// send email
}
}
In this case, the action option can be omitted from the route definition:
[
'path' => '/notification',
'controller' => NotificationController::class,
],
This approach is especially helpful for endpoints that represent a single operation, such as sending emails, processing payments, or handling webhooks, keeping the routing layer simple and expressive.
Dependency Injection
SigmaPHP supports automatic dependency injection directly inside controller methods. Any supported class type hinted in the action method signature will be automatically resolved and injected by the framework at runtime.
This allows you to work directly with objects such as the HTTP Request, models, or services without manually creating them. The framework handles object creation and lifecycle management, keeping controllers clean, testable, and focused only on application logic.
Constructor Injection
<?php
namespace App\Controllers;
use SigmaPHP\Core\Controllers\BaseController;
use App\Services\UserService;
class MainController extends BaseController
{
/**
* @var UserService $userService
*/
private $userService;
/**
* MainController Constructor
*/
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
}
Method Injection
/**
* Receive Request
*
* @param Request $request
* @return Response
*/
public function postData(Request $request)
{
dd($request);
}