1. declare(strict_types=1) in jeder Datei
Erzwingt Typ-Prüfung ohne Silent Conversion. Kein '5' das plötzlich zu int wird.
<?php
declare(strict_types=1); // erste Zeile nach dem <?php-Tag
2. Immer ===, niemals ==
Type Juggling führt zu Bugs, die niemand mehr nachvollzieht. Strict-Comparison ist immer richtig.
3. Typ-Deklarationen überall
// Nein
function f($a, $b) { return $a + $b; }
// Ja
function summe(int $a, int $b): int {
return $a + $b;
}
4. readonly für Value Objects & DTOs
Unveränderliche Objekte eliminieren eine ganze Kategorie von Bugs. Ab PHP 8.2 auch als Klassen-Modifier.
final readonly class Address
{
public function __construct(
public string $street,
public string $city,
public string $zip,
public string $country,
) {}
}
5. PSR-12 als Code Style
Der offizielle Coding-Standard. Nutze Laravel Pint oder PHP-CS-Fixer, um ihn automatisch anzuwenden.
6. Composer statt require_once
Nutze PSR-4-Autoloading. Manuelle require-Ketten sind ein Signal für schlechten Code.
7. Niemals User-Input direkt in SQL
// Nein — SQL-Injection!
$pdo->query("SELECT * FROM users WHERE id = " . $_GET['id']);
// Ja
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$_GET['id']]);
8. Ausgabe immer escapen
// Nein — XSS!
echo $userInput;
// Ja
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
// In Twig/Blade automatisch durch {{ }}
9. Fehler NIE mit @ unterdrücken
// Nein — verbirgt echte Bugs
@file_get_contents($url);
// Ja — explizit prüfen
$content = file_get_contents($url);
if ($content === false) {
throw new RuntimeException("Konnte $url nicht laden");
}
10. Secrets aus .env, nicht aus Code
// Nein
$apiKey = 'sk_live_abc123...';
// Ja
$apiKey = $_ENV['STRIPE_SECRET'] ?? throw new RuntimeException('STRIPE_SECRET fehlt');
11. Composer-Audit im CI-Pipeline
composer audit --format=json
12. Testing ist nicht optional
Nutze Pest oder PHPUnit. Ohne Tests wirst du dich in 6 Monaten fürchten, deinen eigenen Code zu ändern.