78 Dokumentationen verfügbar

Wissensdatenbank

PHP Performance Optimierung Tipps

Zuletzt aktualisiert: 11.01.2026 um 10:22 Uhr

PHP Performance Optimierung

Langsame PHP-Anwendungen frustrieren Benutzer und schaden dem SEO-Ranking. Diese Anleitung zeigt bewährte Methoden, um PHP-Code zu optimieren, Caching einzurichten und Datenbankabfragen zu beschleunigen.

PHP-Version aktualisieren

Der einfachste Performance-Gewinn: PHP aktuell halten.

PHP Version Performance vs. 5.6 Status
PHP 5.6 Baseline ❌ EOL
PHP 7.4 ~3x schneller ❌ EOL
PHP 8.0 ~3.5x schneller ⚠️ Security only
PHP 8.1 ~3.7x schneller ⚠️ Security only
PHP 8.2 ~4x schneller ✅ Aktiv
PHP 8.3 ~4.2x schneller ✅ Aktuell
# PHP-Version prüfen
php -v

# Bei Ubuntu/Debian upgraden
sudo apt install php8.3 php8.3-fpm php8.3-mysql php8.3-mbstring php8.3-xml

OPcache aktivieren und optimieren

OPcache speichert vorkompiliertes PHP im Speicher:

# php.ini Einstellungen
[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=30000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.save_comments=1

# Für Produktion (keine Änderungen erwartet)
opcache.validate_timestamps=0
⚠️ Wichtig: Bei validate_timestamps=0 müssen Sie OPcache nach Änderungen manuell leeren oder PHP-FPM neu starten.

OPcache-Status prüfen

<?php
// opcache-status.php
$status = opcache_get_status();
echo "Memory used: " . round($status['memory_usage']['used_memory'] / 1024 / 1024, 2) . " MB\n";
echo "Memory free: " . round($status['memory_usage']['free_memory'] / 1024 / 1024, 2) . " MB\n";
echo "Cached scripts: " . $status['opcache_statistics']['num_cached_scripts'] . "\n";
echo "Hit rate: " . round($status['opcache_statistics']['opcache_hit_rate'], 2) . "%\n";

Code-Optimierung

Schleifen optimieren

<?php
// ❌ Schlecht: count() wird bei jeder Iteration aufgerufen
for ($i = 0; $i < count($array); $i++) {
    // ...
}

// ✅ Gut: count() nur einmal
$length = count($array);
for ($i = 0; $i < $length; $i++) {
    // ...
}

// ✅ Noch besser: foreach verwenden
foreach ($array as $item) {
    // ...
}

String-Operationen

<?php
// ❌ Schlecht: Konkatenation in Schleife
$html = '';
foreach ($items as $item) {
    $html .= "<li>{$item}</li>";
}

// ✅ Gut: Array und implode
$parts = [];
foreach ($items as $item) {
    $parts[] = "<li>{$item}</li>";
}
$html = implode('', $parts);

// ✅ Oder: Output Buffering
ob_start();
foreach ($items as $item) {
    echo "<li>{$item}</li>";
}
$html = ob_get_clean();

Variablen und Speicher

<?php
// ❌ Unnötige Variablen
$data = file_get_contents('large-file.json');
$decoded = json_decode($data, true);
$filtered = array_filter($decoded, fn($item) => $item['active']);
$result = array_map(fn($item) => $item['name'], $filtered);

// ✅ Speicher freigeben
$data = file_get_contents('large-file.json');
$decoded = json_decode($data, true);
unset($data); // Speicher freigeben

$filtered = array_filter($decoded, fn($item) => $item['active']);
unset($decoded);

$result = array_map(fn($item) => $item['name'], $filtered);
unset($filtered);

Funktionen vs. Sprachkonstrukte

<?php
// ❌ Langsamer: Funktion
isset($array['key']) ? $array['key'] : 'default';

// ✅ Schneller: Null-Coalescing Operator (PHP 7+)
$array['key'] ?? 'default';

// ❌ Langsamer
if (empty($var)) { }

// ✅ Schneller (wenn Typ bekannt)
if ($var === '' || $var === null) { }

Datenbank-Optimierung

Prepared Statements (auch schneller!)

<?php
// ❌ Schlecht und unsicher
$sql = "SELECT * FROM users WHERE id = " . $userId;
$result = $db->query($sql);

// ✅ Gut: Prepared Statement
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$userId]);
$result = $stmt->fetch();

N+1 Problem vermeiden

<?php
// ❌ N+1 Problem: 1 Query + N Queries
$users = $db->query("SELECT * FROM users")->fetchAll();
foreach ($users as $user) {
    $orders = $db->query("SELECT * FROM orders WHERE user_id = {$user['id']}")->fetchAll();
}

// ✅ Mit JOIN: 1 Query
$sql = "SELECT u.*, o.* FROM users u LEFT JOIN orders o ON u.id = o.user_id";
$results = $db->query($sql)->fetchAll();

// ✅ Oder: 2 Queries mit IN
$users = $db->query("SELECT * FROM users")->fetchAll();
$userIds = array_column($users, 'id');
$orders = $db->query("SELECT * FROM orders WHERE user_id IN (" . implode(',', $userIds) . ")")->fetchAll();

Nur benötigte Spalten laden

<?php
// ❌ Alles laden
$sql = "SELECT * FROM products";

// ✅ Nur was nötig ist
$sql = "SELECT id, name, price FROM products";

Caching implementieren

APCu für Anwendungsdaten

<?php
// APCu für einfaches Caching
function getExpensiveData($key) {
    $cacheKey = 'data_' . $key;
    
    // Aus Cache lesen
    $cached = apcu_fetch($cacheKey, $success);
    if ($success) {
        return $cached;
    }
    
    // Daten berechnen
    $data = expensiveOperation($key);
    
    // In Cache speichern (1 Stunde)
    apcu_store($cacheKey, $data, 3600);
    
    return $data;
}

Redis für verteiltes Caching

<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

function getCachedData($key) {
    global $redis;
    
    $cached = $redis->get($key);
    if ($cached !== false) {
        return json_decode($cached, true);
    }
    
    $data = expensiveOperation($key);
    $redis->setex($key, 3600, json_encode($data));
    
    return $data;
}

PHP-FPM Optimierung

# /etc/php/8.3/fpm/pool.d/www.conf

[www]
; Process Manager
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500

; Bei viel RAM: ondemand oder static testen
; pm = ondemand
; pm.process_idle_timeout = 10s

Profiling und Debugging

Ausführungszeit messen

<?php
$start = microtime(true);

// Code hier

$end = microtime(true);
echo "Ausführungszeit: " . ($end - $start) . " Sekunden";

Xdebug Profiling

# php.ini
xdebug.mode=profile
xdebug.output_dir=/tmp/xdebug
xdebug.start_with_request=trigger

# Dann URL mit ?XDEBUG_PROFILE aufrufen
# Cachegrind-Datei mit KCachegrind oder Webgrind analysieren

Quick Wins Checkliste

  1. ☐ PHP 8.2+ verwenden
  2. ☐ OPcache aktiviert und konfiguriert
  3. ☐ Unnötige Extensions deaktiviert
  4. ☐ Prepared Statements verwenden
  5. ☐ N+1 Queries eliminiert
  6. ☐ Output Caching implementiert
  7. ☐ Session-Handler optimiert (Redis/Memcached)
  8. ☐ Autoloader optimiert (Composer dump-autoload -o)

Weitere Hilfe