# PHP Interview Fragen: 14 Fragen mit Antworten und Raster

> Gute PHP-Interviewfragen prüfen Verständnis statt Auswendigwissen: Typvergleich und strict_types, Enums und readonly-Klassen, Neuerungen wie Property Hooks aus PHP 8.4, sichere Datenbankzugriffe, Tests und Debugging. Lass Kandidaten an echtem Code argumentieren, frag nach Begründungen und bewerte die Antworten mit einem festen Raster, damit Gespräche vergleichbar bleiben.

- URL: https://php-entwickler-gesucht.de/bewerber-pruefen/php-interview-fragen/
- Sprache: de
- Aktualisiert: 2026-10-19
- Herausgeber: PHP-Entwickler gesucht (OnlineBuilders LLC, https://onlinebuilders.biz)

Laut der JetBrains-Umfrage State of PHP 2025 schreiben 32 Prozent der PHP-Entwickler überhaupt keine Tests. 42 Prozent nutzen kein einziges Werkzeug zur Code-Qualität, weder PHPStan noch einen Code-Style-Fixer. Das sind keine Randgruppen. Das ist jeweils ein Drittel bis zwei Fünftel des Marktes.

Für dein Interview heißt das: Die wichtigsten Unterschiede zwischen Kandidaten liegen nicht in der Syntax. Sie liegen darin, wie jemand arbeitet. Die folgenden Fragen sind so gewählt, dass sie beides zeigen.

## Wie ein PHP-Interview aufgebaut sein sollte

Ein gutes technisches Gespräch folgt einem festen Ablauf. Nur dann kannst du zwei Kandidaten fair vergleichen. Wer spontan fragt, bewertet am Ende Sympathie.

**Ablauf eines 90-minütigen technischen Interviews**

1. **10 Minuten** Projekt vorstellen, Stack und Rolle erklären.
2. **20 Minuten** Probeaufgabe besprechen: Entscheidungen begründen lassen.
3. **30 Minuten** Fragen zu Sprache, Datenbank und Sicherheit an konkretem Code.
4. **20 Minuten** Praxis: Tests, Debugging, Deployment, ein Fehler aus dem echten Leben.
5. **10 Minuten** Fragen der Kandidatin oder des Kandidaten.

Die Probeaufgabe vorab spart viel Zeit. Wie sie aussehen sollte und warum sie bezahlt werden sollte, steht im Beitrag zur [PHP-Probeaufgabe](https://php-entwickler-gesucht.de/bewerber-pruefen/php-probeaufgabe-bewerbung/).

## Grundlagen: vier Fragen zu Typen und Vergleichen

### 1. Was gibt dieser Code aus, und warum?

```php
var_dump(0 == 'a');      // bool(false) seit PHP 8, vorher true
var_dump('1' == '01');   // bool(true)
var_dump('10' == '1e1'); // bool(true)
var_dump(100 == '1e2');  // bool(true)
var_dump(null == false); // bool(true)
```

Eine gute Antwort erklärt, dass `==` bei numerischen Strings numerisch vergleicht und dass PHP 8 den Vergleich zwischen Zahl und nicht-numerischem String geändert hat. Wer dann sagt „deshalb nutze ich `===`, außer ich will bewusst lose vergleichen“, hat verstanden, worum es geht.

### 2. Was bewirkt `declare(strict_types=1)`?

Erwartet wird: Skalare Typen in Funktionsaufrufen werden nicht mehr stillschweigend umgewandelt, ein `"5"` an einen `int`-Parameter führt dann zu einem `TypeError`. Pluspunkt, wenn jemand weiß, dass die Einstellung pro Datei gilt und nur für Aufrufe aus dieser Datei wirkt.

### 3. Was passiert in der letzten Zeile?

```php
declare(strict_types=1);

enum Status: string
{
    case Draft = 'draft';
    case Paid = 'paid';
    case Cancelled = 'cancelled';

    public function label(): string
    {
        return match ($this) {
            Status::Draft => 'Entwurf',
            Status::Paid => 'Bezahlt',
            Status::Cancelled => 'Storniert',
        };
    }
}

final readonly class Invoice
{
    public function __construct(
        public string $number,
        public int $amountInCents,
        public Status $status = Status::Draft,
    ) {}
}

$invoice = new Invoice('2026-0042', 129_900);
$invoice->status = Status::Paid;
```

Die Zuweisung wirft einen `Error`, weil readonly-Eigenschaften nach der Initialisierung nicht mehr geändert werden können. Interessanter ist die Anschlussfrage: Wie ändert man den Status trotzdem? Gute Antworten schlagen eine Methode vor, die ein neues Objekt zurückgibt. Wer PHP 8.5 kennt, nennt `clone($this, ['status' => $status])`.

Frag außerdem, warum der Betrag als `int` in Cent gespeichert ist. Wer Gleitkommazahlen für Geldbeträge ablehnt und das begründen kann, hat schon einmal einen Rundungsfehler in einer Rechnung gesucht.

### 4. Warum `match` statt `switch`?

`match` vergleicht strikt, liefert einen Wert zurück, braucht kein `break` und wirft einen `UnhandledMatchError`, wenn kein Fall passt. Im Enum-Beispiel oben heißt das: Kommt ein neuer Status hinzu und niemand ergänzt `label()`, fällt es sofort auf.

## Modernes PHP: zwei Fragen zu 8.4 und 8.5

PHP 8.x läuft laut JetBrains bei 89 Prozent der Befragten. Neue Features zeigen, ob jemand die Sprache verfolgt. Niemand muss alles kennen, aber Neugier ist ein gutes Signal.

### 5. Was ist hier neu, und wozu dient es?

```php
final class Product
{
    public string $sku {
        set(string $value) {
            if (! preg_match('/^[A-Z]{3}-\d{4}$/', $value)) {
                throw new InvalidArgumentException("Ungültige SKU: {$value}");
            }
            $this->sku = $value;
        }
    }

    public private(set) int $stock = 0;

    public function restock(int $quantity): void
    {
        $this->stock += $quantity;
    }
}
```

Das sind Property Hooks und asymmetrische Sichtbarkeit, beide seit PHP 8.4. Die SKU wird bei jeder Zuweisung geprüft, ohne Getter und Setter. Der Lagerbestand ist von außen lesbar, aber nur innerhalb der Klasse schreibbar. Die offizielle Beschreibung steht im [PHP-Handbuch zu Property Hooks](https://www.php.net/manual/de/language.oop5.property-hooks.php).

### 6. Was macht der Pipe-Operator?

Seit PHP 8.5 (November 2025) gibt `|>` den Wert links als Argument an die Funktion rechts weiter. Aus verschachtelten Aufrufen wird eine lesbare Kette. Eine ehrliche Antwort wie „kenne ich vom Namen, noch nicht genutzt“ ist völlig in Ordnung. Ein Problem ist es nur, wenn jemand selbstbewusst etwas Falsches erklärt.

## Datenbank und Sicherheit: drei Fragen, die viel verraten

### 7. Wie verhinderst du SQL-Injection?

Erwartet wird: Prepared Statements mit Platzhaltern, nie Nutzereingaben in den SQL-String einsetzen.

```php
$stmt = $pdo->prepare('SELECT id, email FROM users WHERE email = :email');
$stmt->execute(['email' => $_POST['email'] ?? '']);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
```

Pluspunkt: Die Person weiß, dass Tabellen- und Spaltennamen sich nicht als Platzhalter übergeben lassen und deshalb gegen eine Liste erlaubter Werte geprüft werden müssen.

### 8. Wie speicherst du Passwörter?

`password_hash()` mit `PASSWORD_DEFAULT` und `password_verify()` beim Login. Wer MD5 oder SHA-1 nennt, ist für eine Stelle mit Nutzerdaten nicht bereit. Gute Antworten erwähnen `password_needs_rehash()`, um alte Hashes beim nächsten Login zu aktualisieren.

### 9. Wo entsteht XSS, und wie verhinderst du es?

Ausgabe von Nutzereingaben ohne Escaping im HTML. Gegenmittel: Escaping beim Ausgeben, in reinem PHP mit `htmlspecialchars()`, in Blade oder Twig automatisch. Die Nachfrage, wann das automatische Escaping ausgehebelt wird, trennt erfahrene Leute von anderen. In Blade ist das die Schreibweise mit Ausrufezeichen, in Twig der Filter `raw`.

## Praxis: fünf Fragen zur Arbeitsweise

Diese Fragen haben keine richtige Antwort im Sinne einer Musterlösung. Du hörst auf Konkretheit.

10. Wie sieht ein Test aus, den du zuletzt geschrieben hast, und was hat er abgesichert?
11. Welche Stufe von PHPStan oder Psalm nutzt ihr, und was hat sich dadurch geändert?
12. Wie gehst du vor, wenn eine Seite in Produktion plötzlich fünf Sekunden lädt?
13. Erzähl von einem Bug, den du selbst eingebaut hast. Wie kam er in Produktion, und was hast du danach geändert?
14. Wie prüfst du Code, den ein KI-Assistent vorgeschlagen hat?

Frage 12 zeigt, ob jemand systematisch debuggt. JetBrains meldet, dass 59 Prozent der PHP-Entwickler vor allem mit `var_dump`-artigen Ausgaben debuggen und 39 Prozent einen Debugger wie Xdebug nutzen. Beides ist legitim. Wichtiger ist, ob die Person zuerst misst, etwa mit Logs, Query-Zählung oder einem Profiler, bevor sie rät.

Frage 13 ist die ehrlichste im ganzen Gespräch. Wer behauptet, nie einen Fehler in Produktion gebracht zu haben, hat entweder wenig Erfahrung oder wenig Selbstreflexion.

Für Senior-Rollen kommen Architekturfragen dazu, etwa zum Schneiden von Modulen oder zum Umgang mit Altcode. Die passenden Fragen stehen im Beitrag [Senior-PHP-Entwickler erkennen](https://php-entwickler-gesucht.de/bewerber-pruefen/senior-php-entwickler/). Bei Framework-spezifischen Stellen lohnt zusätzlich ein Blick auf die Unterschiede im Vergleich [Laravel oder Symfony](https://php-entwickler-gesucht.de/bewerber-pruefen/laravel-oder-symfony/).

## Ein Bewertungsraster, das Gespräche vergleichbar macht

Notiere direkt nach dem Gespräch zu jedem Bereich eine Punktzahl von 1 bis 3, bevor du mit anderen sprichst. So beeinflusst die Meinung des lautesten Interviewers nicht die übrigen.

| Bereich | 1 Punkt | 2 Punkte | 3 Punkte |
|---|---|---|---|
| Sprachkern | Lücken bei Typen und Vergleichen | sicher im Alltag | erklärt auch Randfälle |
| Modernes PHP | kennt PHP 7 | nutzt Enums, readonly | kennt 8.4/8.5 und bewertet sie |
| Sicherheit | vage Antworten | Standardmaßnahmen sicher | erkennt Ausnahmen und Fallen |
| Tests und Qualität | testet nicht | testet nach Anweisung | testet aus Überzeugung, nutzt statische Analyse |
| Debugging | rät | geht schrittweise vor | misst zuerst, erklärt Werkzeuge |
| Kommunikation | antwortet knapp ohne Begründung | begründet auf Nachfrage | begründet von sich aus, fragt zurück |

Für eine Mid-Level-Stelle sind 12 von 18 Punkten ein solider Wert. Für Senior-Stellen sollte kein Bereich bei 1 liegen. Diese Schwellen sind eine Empfehlung, keine Norm; passe sie an deine Rolle an.

## Fragen, die du dir sparen kannst

Manche Klassiker stehen in jeder Fragensammlung und bringen wenig. „Was ist der Unterschied zwischen `include` und `require`?“ beantwortet jeder nach zehn Sekunden Suche. Ebenso Fragen nach der Reihenfolge von Funktionsparametern wie bei `strpos` oder `array_search`. Das prüft Gedächtnis, nicht Können.

Auch Rätselaufgaben ohne Bezug zum Alltag, etwa einen Algorithmus an der Tafel zu entwickeln, sagen über PHP-Webentwicklung wenig aus. Wenn du Algorithmen prüfen willst, nimm ein Problem aus deinem eigenen Produkt.

Wenn dir die Zeit für einen sauberen Prozess fehlt, kann auch ein externes Team die technische Bewertung übernehmen oder gleich die Entwicklung, etwa ein Studio wie [OnlineBuilders](https://onlinebuilders.biz/solutions/software-development). Für alle, die selbst einstellen, beginnt der Prozess vorher: mit einer klaren [Stellenanzeige für PHP-Entwickler](https://php-entwickler-gesucht.de/entwickler-suchen/stellenanzeige-php-entwickler/).

Kopiere als Nächstes das Raster in ein gemeinsames Dokument, wähle sechs bis acht der Fragen passend zu deiner Rolle aus und lass einen Kollegen sie einmal probehalber beantworten. Danach weißt du, ob die Fragen in 30 Minuten passen.

## Häufige Fragen

### Wie lange sollte ein technisches PHP-Interview dauern?

60 bis 90 Minuten reichen für ein gründliches Gespräch, wenn vorher eine kurze Probeaufgabe gelaufen ist. Länger wird es selten besser, nur anstrengender. Plane am Ende zehn Minuten für die Fragen der Kandidaten ein.

### Darf ich im Interview Live-Coding verlangen?

Du darfst, aber Live-Coding unter Beobachtung misst vor allem Nervenstärke. Besser funktioniert es, gemeinsam über vorbereiteten Code zu sprechen oder die eingereichte Probeaufgabe zu besprechen. So siehst du, wie jemand denkt, ohne künstlichen Druck.

### Wie gehe ich mit KI-Werkzeugen im Bewerbungsprozess um?

Laut JetBrains nutzen 80 Prozent der PHP-Entwickler regelmäßig KI-Assistenten. Ein Verbot im Bewerbungsprozess ist deshalb wenig realistisch. Frag lieber, wie die Person generierten Code prüft, und lass sie eine Stelle aus ihrer Lösung erklären.

### Welche Fragen sollte ich nicht stellen?

Fragen nach Familienplanung, Religion, Herkunft oder Alter sind tabu und können eine Entschädigung nach dem AGG nach sich ziehen. Die Frage nach dem bisherigen Gehalt verbietet Art. 5 Abs. 2 der EU-Entgelttransparenzrichtlinie, das deutsche Umsetzungsgesetz steht allerdings noch aus.

Foto: Breather breather, CC0 (https://commons.wikimedia.org/wiki/File:Leather_chairs_in_meeting_room_(Unsplash).jpg)