Controllers
===========
Controllers group your application’s business logic into organised classes. In LacePHP your controllers live under ``weave/Controllers``. We’ve structured them so you can:
- **Use a shared base class** to bundle common helpers (request, response, auth, etc.)
- **Keep each action method focused** on handling a single route and returning data or HTML
- **Follow good coding standards** with type hints, clear naming and single-responsibility methods
Helper Functions
----------------
Grab the current request or responder inside any controller:
.. code-block:: php
$request = sole_request();
$responder = kickback();
This keeps your code concise and easy to test.
BaseController for Shared Logic
-------------------------------
Rather than repeating the same calls in every controller, create your own **BaseController**:
.. code-block:: php
request = ShoeRequest::grab();
}
protected function json(array $data, int $status = 200): string
{
return kickback()->json($data, $status);
}
protected function html(string $content, int $status = 200): string
{
return kickback()->html($content, $status);
}
protected function abort(int $code = 404, string $message = ''): string
{
switch ($code) {
case 401:
return kickback()->unauthorized($message);
case 500:
return kickback()->serverError($message);
default:
return kickback()->notFound($message);
}
}
}
Example Controller
------------------
.. code-block:: php
request->input('name', 'Guest');
return $this->json([
'message' => "Hello, {$name}! You laced up LacePHP.",
'version' => '1.0.0'
]);
}
/**
* Responds with HTML on GET /html/{id}
*/
public function html(string $id = ''): string
{
$safeId = htmlspecialchars($id, ENT_QUOTES, 'UTF-8');
return $this->html("
Welcome to LacePHP {$safeId}
");
}
/**
* Simulate an error
*/
public function error(): string
{
return $this->abort(500, 'Something went wrong.');
}
}
Why This Design?
-----------------
- **Constructor Injection**
Pulling `ShoeRequest` into `$this->request` ensures every method uses the same sanitised input object.
- **Shared Helpers**
Moving `json()`, `html()` and `abort()` into a base class avoids duplication and keeps controllers focused.
- **Type Safety & Clarity**
Return types (`: string`) and parameter hints make your code self-documenting and IDE-friendly.
- **Separation of Concerns**
Controllers handle input and output; models handle data; views handle presentation.
Advanced Tips
-------------
- **Dependency Injection**
If you require other services (database, mailer), inject them via your constructor:
.. code-block:: php
public function __construct(UserRepository $users)
{
parent::__construct();
$this->users = $users;
}
- **Validation**
Check and validate inputs before passing them to models:
.. code-block:: php
$email = $this->request->input('email');
if (! filter_var($email, FILTER_VALIDATE_EMAIL)) {
return $this->abort(422, 'Invalid email address');
}
- **Consistency**
Keep one controller per feature area and name methods after HTTP actions (for example `index()`, `show()`, `store()`, `update()`).
.. warning::
- **Do not** mix raw `header()` or `echo` calls inside controllers—always return through your responder methods.
- **Escape all output** when rendering HTML to prevent cross-site scripting.
- **Keep logic thin**—move complex operations into services or models for better maintainability and testing.
With this pattern your LacePHP controllers remain clean, maintainable and ready to evolve as your application grows.
|
|