A service layer contains application use cases between controllers and persistence abstractions.
What It Does and When to Use It
Separate business logic, input handling and rendering at a clearly identified boundary. Controllers translate HTTP input to operations; domain services implement rules; templates render escaped output.
Requirements, Inputs and Expected Behavior
Confirm the runtime, extension, environment variables, and permissions before running the examples in production. Avoid making services merely pass-through wrappers with no behavior.
Example 1: Basic Operation
Separate business logic, input handling and rendering at a clearly identified boundary.
<?php
final class OrderService { public function __construct(private PDO $pdo) {} public function countOrders(): int { return (int)$this->pdo->query('SELECT COUNT(*) FROM orders')->fetchColumn(); } }
// The controller delegates business operations to OrderService.
Example 2: Behavior and Validation
Use the front controller to select responses while keeping routing separate from models.
<?php
$path=parse_url($_SERVER['REQUEST_URI']??'/',PHP_URL_PATH);
if ($path==='/health') { header('Content-Type: application/json'); echo json_encode(['status'=>'ok']); }
else { http_response_code(404); echo 'Not found'; }
Practical Example: Application Use
Render a trusted template path with controlled data; never derive template paths from user input.
<?php
function render(string $template, array $data): string {
extract($data, EXTR_SKIP); ob_start();
try { require $template; return (string)ob_get_clean(); }
catch(Throwable $e) { ob_end_clean(); throw $e; }
}
Important Behavior and Edge Cases
The second example highlights: Use the front controller to select responses while keeping routing separate from models. The practical example adds: Render a trusted template path with controlled data; never derive template paths from user input.
Comparison with Related Approaches
| Approach | What changes |
|---|---|
| Controller, service and template responsibilities | Controllers translate HTTP input to operations; domain services implement rules; templates render escaped output. |
| Choosing safely | Treat template names, route parameters and user data as separate trust domains. |
Common Beginner Mistakes
| Mistake | Correct approach |
|---|---|
| Assuming successful execution proves the result is usable | Check the return value, required extension, and observable output of the specific operation. |
| Ignoring runtime and environment differences | Verify PHP version, SAPI, operating system, service access, and permissions before deployment. |
| Skipping operational constraints | Avoid making services merely pass-through wrappers with no behavior. |
Key Takeaways
- A service layer contains application use cases between controllers and persistence abstractions.
- Render a trusted template path with controlled data; never derive template paths from user input.
- Treat template names, route parameters and user data as separate trust domains.