PHP Autoloading PSR4
PHP Autoloading: Klassen automatisch laden mit PSR-4
Schluss mit endlosen require-Statements! Mit Autoloading werden PHP-Klassen automatisch geladen, wenn sie benötigt werden. Der Standard ist PSR-4.
Warum Autoloading?
// ❌ OHNE Autoloading require 'classes/User.php'; require 'classes/Database.php'; require 'classes/Logger.php'; require 'classes/Auth/Session.php'; require 'classes/Auth/Token.php'; // ... für jede Klasse! // ✅ MIT Autoloading use App\User; use App\Auth\Session; // Klassen werden automatisch geladen!
PSR-4 Standard
PSR-4 definiert, wie Klassennamen auf Dateipfade gemappt werden:
Namespace: App\Controller\UserController
Datei: src/Controller/UserController.php
Regel: Namespace-Teil → Verzeichnis
Klassenname → Dateiname.php
Composer Autoloading einrichten
composer.json
{
"name": "vendor/project",
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Autoloader generieren
composer dump-autoload
Verwenden
<?php // Am Anfang der Anwendung require 'vendor/autoload.php'; // Jetzt können Klassen verwendet werden use App\Controller\UserController; use App\Model\User; $controller = new UserController();
Projektstruktur
projekt/ ├── composer.json ├── vendor/ │ └── autoload.php ├── src/ │ ├── Controller/ │ │ ├── UserController.php │ │ └── ProductController.php │ ├── Model/ │ │ ├── User.php │ │ └── Product.php │ ├── Service/ │ │ └── EmailService.php │ └── App.php ├── public/ │ └── index.php └── tests/
Klassen korrekt definieren
<?php
// src/Controller/UserController.php
namespace App\Controller;
use App\Model\User;
use App\Service\EmailService;
class UserController
{
private EmailService $emailService;
public function __construct(EmailService $emailService)
{
$this->emailService = $emailService;
}
public function create(array $data): User
{
$user = new User($data);
$user->save();
$this->emailService->sendWelcome($user);
return $user;
}
}
<?php
// src/Model/User.php
namespace App\Model;
class User
{
public function __construct(
public string $name,
public string $email
) {}
public function save(): void
{
// Speichern...
}
}
Mehrere Namespaces
{
"autoload": {
"psr-4": {
"App\\": "src/",
"Tests\\": "tests/",
"MyLibrary\\": "lib/"
}
}
}
Classmap Autoloading
Für Dateien die nicht PSR-4 folgen:
{
"autoload": {
"psr-4": {
"App\\": "src/"
},
"classmap": [
"legacy/",
"old-classes/"
]
}
}
Files Autoloading
Für Funktionen und Konstanten:
{
"autoload": {
"psr-4": {
"App\\": "src/"
},
"files": [
"src/helpers.php",
"src/constants.php"
]
}
}
<?php
// src/helpers.php
// Keine Klasse, nur Funktionen
function config(string $key): mixed
{
// ...
}
function view(string $template, array $data = []): string
{
// ...
}
Dev-Autoloading
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
}
}
# Nur Produktion composer dump-autoload --no-dev # Mit Dev-Dependencies composer dump-autoload
Optimierung für Produktion
# Optimierte Classmap generieren composer dump-autoload --optimize # Oder bei Install composer install --optimize-autoloader --no-dev
Eigener Autoloader (ohne Composer)
<?php
// Einfacher PSR-4 Autoloader
spl_autoload_register(function (string $class): void {
// Namespace-Präfix und Basis-Verzeichnis
$prefix = 'App\\';
$baseDir = __DIR__ . '/src/';
// Passt die Klasse zum Präfix?
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
// Relativer Klassenname
$relativeClass = substr($class, $len);
// Datei-Pfad
$file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
// Datei laden wenn vorhanden
if (file_exists($file)) {
require $file;
}
});
Häufige Fehler
❌ Häufige Fehler:
- Namespace stimmt nicht mit Verzeichnis überein
- Dateiname stimmt nicht mit Klassennamen überein
- Groß-/Kleinschreibung falsch (Linux ist case-sensitive!)
composer dump-autoloadvergessen
# Debug: Welche Datei wird für Klasse gesucht? composer dump-autoload -vvv
💡 Tipp:
Modernes PHP verwendet immer PSR-4 Autoloading. Es macht den Code übersichtlicher und ermöglicht echte OOP.