php
51 lines · 8 steps
Enforcing upload quotas with Laravel middleware
A middleware that blocks file uploads when a team's incoming bytes would exceed its subscription plan's storage quota.
Explained by
highlit
1<?php
2
3namespace App\Http\Middleware;
4
5use Closure;
6use Illuminate\Http\Request;
7use Symfony\Component\HttpFoundation\Response;
8
9class EnforceUploadQuota
10{
11 protected array $planLimits = [
12 'free' => 100 * 1024 * 1024,
13 'pro' => 5 * 1024 * 1024 * 1024,
14 'enterprise' => 100 * 1024 * 1024 * 1024,
15 ];
16
17 public function handle(Request $request, Closure $next): Response
18 {
19 $team = $request->user()->currentTeam;
20
21 abort_unless($team, 403, 'You must belong to a team to upload files.');
22
23 $plan = $team->subscription('default')?->stripe_price
24 ? $team->planName()
25 : 'free';
26
27 $quota = $this->planLimits[$plan] ?? $this->planLimits['free'];
28
29 $incoming = collect($request->allFiles())
30 ->flatten()
31 ->sum(fn ($file) => $file->getSize());
32
33 $projected = $team->storage_used + $incoming;
34
35 if ($projected > $quota) {
36 $remaining = max(0, $quota - $team->storage_used);
37
38 return response()->json([
39 'message' => "Upload exceeds your {$plan} plan quota.",
40 'quota_bytes' => $quota,
41 'used_bytes' => $team->storage_used,
42 'remaining_bytes' => $remaining,
43 'upgrade_url' => route('billing.plans'),
44 ], Response::HTTP_PAYMENT_REQUIRED);
45 }
46
47 $request->attributes->set('upload_bytes', $incoming);
48
49 return $next($request);
50 }
51}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Middleware is the right place to reject requests before controllers run wasteful work.
- 2Summing incoming file sizes against a known limit lets you fail fast with a precise, actionable error.
- 3Passing computed data downstream via request attributes avoids recomputing it in the controller.
Related explainers
php
<?php class NameParser {
Parsing a full name into components in PHP
string-parsing
arrays
normalization
Intermediate
8 steps
php
<?php namespace App\Services\Checkout;
Validating coupons with Laravel's Pipeline
pipeline
chain of responsibility
transactions
Intermediate
7 steps
python
import time import uuid from django.utils.deprecation import MiddlewareMixin
Attaching per-request context in Django
middleware
request lifecycle
multi-tenancy
Intermediate
7 steps
php
<?php namespace App\Services;
How a password strength validator works in PHP
validation
regular-expressions
data-driven
Intermediate
8 steps
php
<?php namespace App\Services;
Building a cached daily leaderboard in Laravel
caching
aggregation
eager-loading
Intermediate
9 steps
php
<?php final class RotatingFileLogger {
How a rotating file logger works in PHP
logging
file-rotation
io
Intermediate
9 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/enforcing-upload-quotas-with-laravel-middleware-explained-php-283b/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.