dev-resources.site
for different kinds of informations.
PSR-4: Autoloading Standard in PHP
Ahnii!
Remember the old days of PHP when we had to manually require
every single file? π
Last week, I was helping a team modernize their legacy application that had 50+ require statements at the top of each file. Let me show you how PSR-4 autoloading makes this a problem of the past!
Understanding PSR-4 (5 minutes)
Think of PSR-4 as your codeβs GPS system - it helps PHP find the right files automatically. Just like how a GPS uses addresses to find locations, PSR-4 uses namespaces to locate classes.
Key Concepts (2 minutes)
- π Fully Qualified Class Name (FQCN)
- Vendor namespace (like your brand)
- Package namespace (like your project)
- Class name (the actual file)
- π Directory Structure
- Base directory (where everything starts)
- Namespace mapping (your GPS coordinates)
- File location rules (the actual addresses)
Real-World Example (10 minutes)
Hereβs how I structure my projects:
vendor/
βββ jonesrussell/
βββ blog/
βββ composer.json
βββ src/
βββ Post/
βββ PostController.php
βββ PostRepository.php
1. Setting Up Composer (3 minutes)
{
"name": "jonesrussell/blog",
"autoload": {
"psr-4": {
"JonesRussell\\Blog\\": "src/"
}
}
}
2. Creating Classes (2 minutes)
<?php
namespace JonesRussell\Blog\Post;
class PostController
{
public function index()
{
return ['status' => 'Ready to blog!'];
}
}
Common Patterns I Use (5 minutes)
1. π― Multiple Namespace Roots
{
"autoload": {
"psr-4": {
"JonesRussell\\Blog\\": "src/",
"JonesRussell\\Blog\\Tests\\": "tests/"
}
}
}
2. π³ Nested Namespaces
<?php
namespace JonesRussell\Blog\Core\Database;
class Connection
{
private $config;
public function __construct(array $config)
{
$this->config = $config;
}
}
// File location: src/Core/Database/Connection.php
Framework Examples (5 minutes)
If youβre using Laravel or Symfony (like I do), they follow PSR-4 out of the box:
Laravel
<?php
namespace App\Http\Controllers;
class BlogController extends Controller
{
public function index()
{
return view('blog.index');
}
}
Symfony
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class BlogController extends AbstractController
{
public function index(): Response
{
return $this->render('blog/index.html.twig');
}
}
Quick Fixes for Common Issues (3 minutes)
- π βClass Not Foundβ Errors
# When things go wrong, this is your friend:
composer dump-autoload
- π― Directory Structure Mistakes
# Don't do this
src/
βββ controllers/ # lowercase = bad
βββ PostController.php
# Do this instead
src/
βββ Controller/ # Matches namespace case
βββ PostController.php
Testing Your Setup (2 minutes)
Drop this in test-autoload.php
:
<?php
require 'vendor/autoload.php';
// If this works, your autoloading is set up correctly!
$controller = new \JonesRussell\Blog\Post\PostController();
var_dump($controller->index()); // Should show "Ready to blog!"
Next Steps
Tomorrow, weβll explore PSR-6 and see how it standardizes caching in PHP applications. This post is part of our PSR Standards in PHP series.
Resources
- Official PSR-4 Specification
- Composer Autoloading Documentation
- Series Example Repository (v0.3.0 - PSR-4 Implementation)
Featured ones: