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
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Constructor property promotion collapses dependency injection into a single readonly parameter.
- 2Validating and normalizing input before persisting keeps bad data out of the repository.
- 3Centralizing status codes and JSON encoding in one helper keeps every response consistent.
Related explainers
php
<?php final class RememberMeCookie {
Signed remember-me cookies in PHP
authentication
hmac
cookies
Intermediate
8 steps
java
@Component public class HeaderMergeFilter { private static final String PER_REQUEST_HEADERS = HeaderMergeFilter.class.getName() + ".headers";
Merging default and per-request headers in Spring
webclient
filters
http-headers
Intermediate
8 steps
php
<?php namespace App\Http\Middleware;
Caching HTTP responses with Laravel middleware
middleware
caching
http
Intermediate
8 steps
java
public record AppConfig( String host, int port, String databaseUrl,
Loading typed config from env vars in Java
records
configuration
environment-variables
Intermediate
6 steps
php
<?php namespace App\Validation;
Building a reusable address form validator in PHP
validation
error-accumulation
regex
Intermediate
9 steps
php
<?php namespace App\Http\Controllers;
A cached autocomplete endpoint in Laravel
caching
validation
query-ranking
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/a-single-action-json-user-controller-in-php-explained-php-1892/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.