PHP für Webentwicklung: Moderne Praxis statt Legacy-Code

PHP treibt noch immer rund drei Viertel aller Websites an – von kleinen Blogs bis zu großen Systemen wie WordPress, Joomla oder Laravel-Anwendungen. Der schlechte Ruf aus den 2000er-Jahren ist längst überholt: Modernes PHP (ab Version 8) ist typsicher, schnell und gut testbar. Dieser Artikel zeigt, wie zeitgemäße PHP-Entwicklung aussieht und worauf es in der Praxis ankommt.

Warum PHP 2026 immer noch relevant ist

  • Verbreitung: Kaum ein Shared-Hosting-Anbieter ohne PHP-Unterstützung – günstig und überall verfügbar.
  • Reife Ökosysteme: Composer als Paketmanager, Frameworks wie Laravel und Symfony, CMS wie Joomla und WordPress.
  • Performance: Mit PHP 8.x und OpCache ist PHP für die meisten Web-Anwendungen schnell genug – und mit FrankenPHP (Go-basierter App-Server) sogar für anspruchsvollere Last.
  • Einfacher Einstieg: Eine Datei, ein Webserver, fertig. Ideal für Prototypen und kleinere Dienste.

Grundlagen: Variablen, Arrays, Funktionen

<?php
$name = "Michael";
$alter = 42;
$preise = [12.99, 8.50, 3.20];        // Array
$nutzer = ["id" => 1, "name" => "ki"]; // Assoziatives Array

function brutto(float $netto, float $satz = 0.19): float {
    return $netto * (1 + $satz);
}
echo brutto(100.0); // 119.0
?>

Wichtig: PHP-Dateien, die nur Logik enthalten, schließen ohne ?> – das verhindert versehentlich ausgegebenen Whitespace, der Header-Probleme verursacht.

Moderne Sprachelemente (PHP 8+)

Seit PHP 8.0 (November 2020) hat sich die Sprache fundamental verbessert:

  • Named Arguments: function erstelle_user(name: "ki", admin: true) – Argumente beim Namen nennen.
  • Union Types: function finde(int|string $id): ?User – präzise Typen statt Docblocks.
  • Match-Ausdruck: Ersetzt lange switch-Ketten: $status = match($code) { 200 => 'ok', 404 => 'missing', default => 'unknown' };
  • Nullsafe-Operator: $user?->profil?->email – bricht sauber bei null ab.
  • Readonly-Klassen und Enums: Seit 8.1/8.2 für klare Domänenmodelle.

Projektstruktur und Composer

Composer ist der Paketmanager – so wie pip für Python oder npm für JavaScript:

composer require guzzlehttp/guzzle   # HTTP-Client
composer require vlucas/phpdotenv    # .env-Konfiguration

Eine saubere, kleine Struktur für ein Web-Projekt:

projekt/
  public/          # DocumentRoot – nur hier liegt Erreichbares
    index.php      # Front-Controller (Router)
  src/             # Anwendungscode
  config/          # Konfiguration
  vendor/          # Composer-Abhängigkeiten (nie ins Git!)

Der Front-Controller leitet alle Requests an index.php weiter. Dazu eine .htaccess (Apache) oder eine nginx-Konfiguration mit try_files $uri $uri/ /index.php?$query_string;.

Sicherheit: Die vier häufigsten Fallen

  1. SQL-Injection: Nie Werte direkt in Queries concatenaten. Immer Prepared Statements (PDO):
$stmt = $pdo->prepare("SELECT * FROM user WHERE email = ?");
$stmt->execute([$email]);
  1. XSS (Cross-Site Scripting): Jede Ausgabe escapen: <?= htmlspecialchars($wert, ENT_QUOTES, 'UTF-8') ?>
  2. CSRF: Bei Formularen ein Token mitsenden und prüfen (z.B. $_SESSION['csrf']).
  3. Datei-Uploads: Erlaubte MIME-Typen whitelisten, Dateien außerhalb des Webroots speichern und per Hash umbenennen.

Wer diese vier Regeln befolgt, ist bereits sicherer als die Mehrheit der PHP-Anwendungen im Internet.

Praxis: Kleine REST-API mit PDO

<?php
declare(strict_types=1);
require 'vendor/autoload.php';

$pdo = new PDO(
    'mysql:host=localhost;dbname=app;charset=utf8mb4',
    getenv('DB_USER'), getenv('DB_PASS'),
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);

header('Content-Type: application/json');
$stmt = $pdo->query("SELECT id, titel FROM artikel ORDER BY id DESC LIMIT 10");
echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC));

So entstehen in wenigen Minuten funktionierende JSON-Endpunkte – das Grundmuster hinter vielen Web-APIs, auch im Hanse-Computing-Umfeld (z.B. Webradio-API, siehe HTTP/HTTPS-Grundlagen).

Deployment in der Praxis

  • OpCache aktivieren (opcache.enable=1, opcache.validate_timestamps=0 in Produktion).
  • Fehleranzeige aus: display_errors=0, stattdessen Logs (error_log).
  • Composer mit composer install --no-dev --optimize-autoloader.
  • Dateirechte: Webserver darf nur lesen, Schreibzugriff nur wo nötig (Uploads, Cache).
  • Backups und Deploy-Strategie: Siehe Systemadministration.
  • Fehlerbehandlung und Logging

    Fehler verschlucken ist die häufigste PHP-Sünde. Modernes PHP unterscheidet sauber zwischen Exceptions (programmgesteuert) und Fehlern (Laufzeit):

    try {
        $stmt = $pdo->prepare("SELECT * FROM user WHERE id = ?");
        $stmt->execute([$id]);
        $user = $stmt->fetch();
        if (!$user) {
            throw new RuntimeException("User nicht gefunden");
        }
    } catch (PDOException $e) {
        error_log("DB-Fehler: " . $e->getMessage());
        http_response_code(500);
        echo json_encode(["error" => "Interner Fehler"]);
    }

    Wichtig: Dem Nutzer niemals rohe Fehlermeldungen zeigen – die enthüllen Datenbankstruktur und Pfade. In Produktion gilt display_errors=0, alles geht ins Log. Für strukturierte Fehlerüberwachung bieten sich Sentry oder einfache Log-Aggregation an (siehe Monitoring in der Systemadministration).

    Gemeinsame Nutzung mit Datenbanken: PDO richtig einsetzen

    PDO ist der moderne Datenbank-Zugang (MySQL/MariaDB, PostgreSQL, SQLite). Die wichtigsten Details:

    $pdo = new PDO(
        'mysql:host=localhost;dbname=app;charset=utf8mb4',
        $user, $pass,
        [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false,
        ]
    );
    
    // Transaktion: entweder alles oder nichts
    $pdo->beginTransaction();
    try {
        $pdo->exec("UPDATE konto SET saldo = saldo - 100 WHERE id = 1");
        $pdo->exec("UPDATE konto SET saldo = saldo + 100 WHERE id = 2");
        $pdo->commit();
    } catch (Throwable $e) {
        $pdo->rollBack();
        throw $e;
    }

    Transaktionen verhindern, dass bei einem Fehler halbe Buchungen zurückbleiben. ATTR_EMULATE_PREPARES = false nutzt echte Prepared Statements des Servers – schneller und sicherer. Die Grundlagen zu SQL selbst finden Sie im Artikel SQL-Grundlagen.

    Fazit

    PHP ist 2026 eine pragmatische, gut wartbare Wahl – besonders dort, wo Hosting-Umgebungen vorgegeben sind (Joomla, WordPress) oder schnelle Ergebnisse zählen. Wer moderne Features nutzt, auf Sicherheit achtet und sauber strukturiert, entwickelt damit genauso professionell wie mit jeder anderen Sprache. Die Grundlagen zu SQL-Datenbanken finden sich im Artikel SQL-Grundlagen.

    Verwandte Artikel: Python für Einsteiger · SQL-Grundlagen · Systemadministration