‚Fatal error: Cannot use lexical variable $xxx as a parameter name‘ beheben

Schonmal diesen Fehler erhalten? Fatal error: Cannot use lexical variable $xxx as a parameter name. In der Regel erhalten Sie diesen Fehler bei der Umstellung auf die PHP-Version 7.1.x. Hier steht, wie man den Fehler beheben kann:

Was sind „lexical variables“?

Zu deutsch sind die „lexikalischen Variablen“ die Variablen die in einem „Namensraum“ registriert sind. Folgendes ist vollkommen in Ordnung (Beispiel 1):

$section_id = 1;

function test() {
   $section_id = 1;
}

Beide Variablen haben den selben Namen aber sie stören sich nicht. Denn die erste Variable ist in einem anderen „Raum“ als Letztere.

Um Zugriff auf die Variable zu bekommen, müsste man diese innerhalb der Funktion test() letztlich global verfügbar machen. Aber das ist ein anderes Thema.

Das eigentliche Problem

Nutzt man so genannte Closures zusammen mit anonymen Funktionen, könnte man folgendes bauen (Beispiel 2):

$section_id = 1;

$function = function ( $s_id ) use ( $section_id ) {

   // ... $s_id hat den Wert von $section_id ...
};

Durch das Schlüsselwort use lassen sich Variablen an die anonyme Funktion übergeben. Alles bestens. Was ist, wenn man aber die gleichen Variablennamen nutzt? So wie folgt (Beispiel 3):

$section_id = 1;

$function = function ( $section_id ) use ( $section_id ) {

   // ... $section_id hat den Wert von $section_id. Logisch ...
};

Beispiel 3 funktioniert nur in PHP kleiner oder gleich 7.0.x. Diese Unit-Tests zeigen den konkreten Fall noch einmal. Das Problem sind also die gleichen Variablennamen. Warum das gemacht wurde, weiß ich nicht genau. Den entsprechenden C-Code dahinter habe ich nicht analysiert. Aber vermutlich hat es etwas mit dem sich überschneidenden Namensraum zu tun.

Einer Änderung der Dokumentation kann man sauber leserlich entnehmen, dass die Änderung gewollt war und das wohl auch so bleiben wird. Einigen Unterhaltungen in Foren kann man entnehmen, dass das früher schon hätte verändert werden sollen. Wie dem auch sei. Es ist jetzt so, wie es ist. Das heißt: Die Nutzung von gleichen Variablennamen in Closures sind ab PHP 7.1.x verboten.