Zwischen einzelnen Variablen und einem assoziativen Array hin und her zu wechseln, ist eine wiederkehrende Aufgabe im PHP-Alltag. Mit PHP compact und der Gegenfunktion extract gibt es dafür ein eingebautes Paar, das den Code kürzer macht. Dieser Beitrag zeigt beide Funktionen, das klassische Template-Pattern und die Sicherheitsfallen, die bei extract lauern.
Was machen compact() und extract()?
Wer in PHP regelmäßig mehrere Variablen an eine andere Stelle übergeben muss, etwa an ein Template oder eine Logger-Funktion, kennt die Versuchung, das Array von Hand zu schreiben: ['name' => $name, 'alter' => $alter, 'land' => $land]. Das ist nicht falsch, aber unnötig länglich. Genau dafür gibt es PHP compact: Die Funktion erstellt aus einer Liste von Variablennamen ein assoziatives Array, in dem die Schlüssel den jeweiligen Variablennamen und die Werte den Variableninhalten entsprechen. Jeder übergebene Variablenname wird dabei zum Schlüssel, jeder Inhalt zum zugehörigen Wert. Das Gegenstück extract() dreht die Operation um und erzeugt aus einem Array Variablen im aktuellen Scope, sodass man auf jede Variable direkt zugreifen kann.

Bevor das MVC-Template-Pattern und die EXTR_-Flags zur Sprache kommen, lohnt sich ein kurzer Blick auf die Risiken im Umgang mit beiden Funktionen.
So elegant das aussieht, so vorsichtig muss man dabei sein. PHP compact() ist im Alltag harmlos, extract() dagegen kann bei unbedachtem Einsatz auf User-Input zu Sicherheitslücken führen. Das Tutorial zeigt beide Funktionen Schritt für Schritt, erklärt das klassische MVC-Template-Pattern und macht klar, wann der Einsatz heute noch sinnvoll ist.
Syntax und Aufrufvarianten von compact()
PHP compact() kann variadisch mit beliebig vielen Variablennamen als Argument oder mit einem Array von Strings aufgerufen werden. Beide Varianten erzeugen dasselbe assoziative Array. Die folgenden Beispiele zeigen beide Aufrufstile.
<?php
compact(string|array $var_name, string|array ...$var_names): array
Der Rückgabewert ist immer ein Array. Existiert eine genannte Variable nicht, war das früher ein stilles Auslassen, ab PHP 8.1 wirft compact() dafür eine Warning. Diese Verhaltensänderung sorgt für mehr Klarheit, weil ein Tippfehler im Variablennamen sofort auffällt.
Erstes Beispiel: drei Variablen einpacken
Zum Einstieg ein einfacher Aufruf mit drei Variablen. PHP compact() erzeugt ein assoziatives Array, in dem die Variablennamen als Schlüssel dienen.
<?php
$name = 'Anna';
$alter = 28;
$land = 'DE';
$person = compact('name', 'alter', 'land');
print_r($person);
/* Array ( [name] => Anna [alter] => 28 [land] => DE ) */
Die Schreibweise ist deutlich kompakter als ['name' => $name, 'alter' => $alter, 'land' => $land]. Wer eine große Anzahl Variablen übergeben muss, etwa zehn Felder eines Formulars, spart mit PHP compact() viele Zeichen und macht das Bindeglied zwischen Variablenname und Schlüsselname automatisch konsistent.
extract() und das Symboltable-Konzept
Die Schwester-Funktion extract() macht den umgekehrten Schritt. Sie nimmt ein assoziatives Array und erzeugt für jeden Schlüssel eine Variable im aktuellen Scope. Die Schlüssel werden zu Variablennamen, die Werte zu Variableninhalten.
<?php
$daten = ['name' => 'Anna', 'alter' => 28];
extract($daten);
echo $name . ' ' . $alter;
/* Ausgabe: Anna 28 */
Technisch greift extract direkt in das Symboltable des aktuellen Scopes ein und legt dort neue Variablen an. Das ist mächtig, kann aber auch überraschen: Wenn eine Variable mit demselben Namen bereits existiert, wird sie standardmäßig überschrieben. Wer das nicht will, nutzt EXTR_SKIP, das im nächsten Abschnitt vorgestellt wird.
Praxisfall MVC-Template-Pattern
Das klassische Anwendungsfeld der beiden Funktionen ist das selbst gebaute Template-System. Ein Controller bereitet Variablen vor und übergibt sie an eine Render-Funktion, die sie im Template wieder entpackt. Das Pattern ist seit zwei Jahrzehnten in PHP-Codebases zu finden.
<?php
function render(string $template, array $vars): string {
extract($vars, EXTR_SKIP);
ob_start();
include $template;
return ob_get_clean();
}
/* Im Controller */
$titel = 'Startseite';
$user = 'Anna';
$jahr = 2026;
echo render('header.tpl.php', compact('titel', 'user', 'jahr'));
Das Pattern kombiniert PHP compact() im Controller, Output-Buffering mit ob_start() in der Render-Funktion und einen klassischen include für das Template. Im Template-File stehen $titel, $user und $jahr direkt zur Verfügung. Diese Variante ist die Grundidee jeder modernen PHP-Template-Engine wie Twig oder Blade, die intern ähnlich arbeiten.
Sicherheitsrisiko: extract auf User-Input
Wer extract bedenkenlos auf User-Input loslässt, öffnet eine Sicherheitslücke. Mit extract($_GET) könnte ein Angreifer beliebige Variablen im aktuellen Scope überschreiben, etwa eine $is_admin-Variable, die später im Code ausgewertet wird.
<?php
/* GEFAEHRLICH: nicht so machen */
$is_admin = false;
extract($_GET);
if ($is_admin) {
echo 'Admin-Bereich';
}
/* URL ?is_admin=1 wuerde ausreichen */
Die saubere Lösung ist, extract niemals direkt auf $_GET, $_POST oder $_COOKIE anzuwenden. Falls die Daten wirklich entpackt werden müssen, sollte vorher ein expliziter Whitelist-Filter mit array_intersect_key() greifen und der EXTR_SKIP-Flag verhindern, dass bestehende Variablen überschrieben werden.
<?php
$is_admin = false;
$erlaubt = ['name' => '', 'alter' => 0];
$gefiltert = array_intersect_key($_GET, $erlaubt);
extract($gefiltert, EXTR_SKIP);
/* $is_admin bleibt false, nur name und alter werden entpackt */
Diese defensive Variante ist die einzige, die in produktivem Code Anwendung finden sollte. Wer das Pattern nicht braucht, sollte extract auf User-Input ganz vermeiden.
flowchart TD
A[Variablen name alter] --> B[compact]
B --> C[Assoziatives Array]
C --> D[extract]
D --> E[Variablen name alter]
Die EXTR_-Flags im Überblick
extract() hat einen zweiten Parameter, der das Verhalten bei Konflikten steuert. Die wichtigsten Flags sind in der Praxis EXTR_SKIP und EXTR_PREFIX_ALL.
<?php
$name = 'Original';
/* EXTR_OVERWRITE (Default): Original wird ueberschrieben */
extract(['name' => 'Neu'], EXTR_OVERWRITE);
echo $name;
/* Ausgabe: Neu */
/* EXTR_SKIP: bestehende Variablen bleiben */
$name = 'Original';
extract(['name' => 'Neu'], EXTR_SKIP);
echo $name;
/* Ausgabe: Original */
/* EXTR_PREFIX_ALL: alle Variablen bekommen einen Prefix */
extract(['name' => 'Anna', 'rolle' => 'admin'], EXTR_PREFIX_ALL, 'user');
echo $user_name . ' ' . $user_rolle;
/* Ausgabe: Anna admin */
EXTR_SKIP ist die defensive Wahl in Render-Funktionen, weil bereits definierte Variablen wie $this nicht überschrieben werden sollen. EXTR_PREFIX_ALL ist nützlich, wenn mehrere Datenquellen gleichzeitig entpackt werden und Konflikte vermieden werden sollen, etwa wenn aus einem User-Array $user_name und aus einem Order-Array $order_id entstehen sollen.
Verhalten bei undefinierten Variablen ab PHP 8.1
Vor PHP 8.1 wurden in PHP compact() einfach übersprungen, wenn eine genannte Variable nicht existierte. Ab PHP 8.1 wirft die Funktion eine Warning, die im Logger landet und im Strict-Modus auch zu Errors führen kann.
<?php
$name = 'Anna';
$result = compact('name', 'alter');
/* PHP 8.1+: Warning: compact(): Undefined variable $alter */
Die Änderung ist sinnvoll, weil sie Tippfehler in Variablennamen sofort sichtbar macht. Wer die Warning nicht im Logger haben will, sollte vor dem Aufruf alle Variablen mit isset() prüfen oder Default-Werte zuweisen. In Render-Funktionen ist das ein guter Anlass, die Variable bewusst auf null zu setzen, statt sie heimlich verschwinden zu lassen.
Wann compact und extract heute noch sinnvoll sind
In modernen PHP-Projekten mit Frameworks wie Symfony oder Laravel kommen PHP compact() und extract() selten direkt zum Einsatz, weil Twig, Blade und andere Template-Engines die Variable-Übergabe intern übernehmen. Wer trotzdem ein eigenes kleines Template-System baut, etwa für ein Admin-Tool ohne Framework, profitiert weiterhin von dem Pattern.
PHP compact() ist auch in Logger-Aufrufen praktisch, wenn mehrere Kontextvariablen mitgegeben werden sollen, etwa log('user-aktion', compact('user_id', 'aktion', 'zeitpunkt')). Die Schreibweise ist knapper als die manuelle Array-Notation und konsistent in der Benennung. Wer im Code-Review die Funktion sieht, sollte prüfen, ob das Anwendungsfeld passt und ob die Variablen alle definiert sind.
Fazit
PHP compact() und extract() sind ein altes, aber weiterhin nützliches Funktionspaar, das zwischen Variablen und assoziativen Arrays vermittelt. PHP compact() ist die kompakte Schreibweise für das Erzeugen eines Daten-Arrays aus mehreren Variablen, und extract entpackt diese Daten in einem anderen Scope. Der MVC-Template-Klassiker bleibt eine elegante Anwendung, die Vorsicht bei extract auf User-Input ist Pflicht. Wer die EXTR_-Flags kennt, niemals direkt auf $_GET extract anwendet und ab PHP 8.1 die Warning bei undefinierten Variablen ernst nimmt, hat mit PHP compact() ein zuverlässiges Werkzeug für den Alltag im PHP-Backend.