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. | |