php 52 lines · 7 steps

A single-action JSON user controller in PHP

An invokable controller parses a JSON request, validates it, creates a user, and returns a structured response.

Explained by highlit
1<?php
2 
3declare(strict_types=1);
4 
5namespace App\Http;
6 
7final class CreateUserController
8{
9 public function __construct(private readonly UserRepository $users)
10 {
11 }
12 
13 public function __invoke(): void
14 {
15 header('Content-Type: application/json');
16 
17 $raw = file_get_contents('php://input');
18 $payload = json_decode($raw ?: '', true, 512, JSON_THROW_ON_ERROR);
19 
20 if (!is_array($payload) || empty($payload['email']) || empty($payload['name'])) {
21 $this->respond(422, [
22 'error' => 'Validation failed',
23 'fields' => ['email', 'name'],
24 ]);
25 return;
26 }
27 
28 $email = filter_var($payload['email'], FILTER_VALIDATE_EMAIL);
29 
30 if ($email === false) {
31 $this->respond(422, ['error' => 'Invalid email address']);
32 return;
33 }
34 
35 $user = $this->users->create(
36 name: trim((string) $payload['name']),
37 email: $email,
38 );
39 
40 $this->respond(201, [
41 'id' => $user->id,
42 'name' => $user->name,
43 'email' => $user->email,
44 ]);
45 }
46 
47 private function respond(int $status, array $body): void
48 {
49 http_response_code($status);
50 echo json_encode($body, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES);
51 }
52}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Constructor property promotion collapses dependency injection into a single readonly parameter.
  2. 2Validating and normalizing input before persisting keeps bad data out of the repository.
  3. 3Centralizing status codes and JSON encoding in one helper keeps every response consistent.

Related explainers

Share this explainer

Here's the card — post it anywhere.

A single-action JSON user controller in PHP — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code