Gunther: eval nicht mit mehrdimensionalen Arrays möglich?

Beitrag lesen

Moin Sven!

Vorweg: Vielen Dank für deine sehr ausführliche & hilfreiche Antwort. Außerdem ist so formuliert, dass ich auch folgen kann. ;-)
(@dedlfix: Das gilt natürlich auch für deine Antwort!)

Gewöhne dir diesen äußerst schlechten stil garnicht erst an - das könnte später, wenn es wirklich um Sicherheit oder Performance geht, uncoole folgen haben.
Gut, das Argument zieht natürlich immer. ;-)

Das ist überhaupt das ultimative Argument. eval() erzeugt dir eine ganz dicke, klebrige Schicht Indirektheit. Du hast keine direkte Kontrolle mehr über den ausgeführten Code, sondern nur noch über den Codegenerator, der dann eval() füttert. Codefehler werden nicht mehr direkt angemeckert oder von entsprechenden Tools wie Syntaxhighlighting und Analysewerkzeugen entdeckt. Insgesamt verzichtest du auf eine extrem große Bandbreite von sinnvollen Hilfsmitteln, und holst dir eben die Sicherheitsprobleme und Performancenachteile noch zusätzlich ins Boot.

ACK. Nach meinem Verständnis ist aber ja gerade mein spezieller Anwendungsfall einer, wo sich genau diese Probleme_nicht_ergeben. Grundsätzlich habe ich die Problematik und die Gefahren schon verstanden. Gut, bleibt die Gefahr der möglichen Gewöhnung.

Aber gut, wenn es ja auch anders geht, ohne dass dadurch irgendwelche gravierenden Nachteile entstehen, dann kann man es ebensogut (bzw. besser) gleich anders machen.

  1. Mein Ausgangsfrage: eval() nicht mit mehrdimensionalen Arrays möglich?

Du nutzt in eval() kein mehrdimensionales Array. Du nutzt einen simplen String:
eval ("\$str = \"$str\";");

Also kann das Problem nicht mit eval() zusammenhängen.

Erwischt. Hier ist mir eine sprachliche Ungenauigkeit unterlaufen. Richtig hätte es z.B. so heißen müssen:"In dem zu evaluierenden String möchte ich gerne ...!".

Würdest du dir VOR dem eval() mal $str ausgeben lassen, würdest du sehen, dass dein Ergebnis des eval() auch vor dem eval() schon identisch ist: url: "http://www.example.comArray[pfad]"

Was sagt uns das? Offenbar ist beim Stringzusammenbau von $str was schief gelaufen.

Ja - s.o.

Und wenn man sich die Doku in PHP ansieht, wird man den Grund auch finden: In doppelten Anführungszeichen kann man nur einfache Variablen direkt verwenden, also z.B. so
$str = "url: $irgendwas";

Man kann auch eindimensionale Arrays verwenden, wenn man den Array-Index-String OHNE Anführungszeichen schreibt:
$str = "url: $irgendwas[index]";

Im Gegensatz dazu muss man ja bei Array-Notation außerhalb den Index-String in Anführungszeichen schreiben:
$str = $irgendwas['index'];

Innerhalb von doppelten Anführungszeichen dürfen komplexere Variablen bzw. auch Objekte nur vorkommen, wenn man sie in geschweifte Klammern setzt:
$str = "url: {$irgendwas['index'][2]}";

Dann ist aber auch wieder zwingend das Nutzen von Anführungszeichen um den Index-String notwendig!
http://php.net/manual/en/language.types.array.php#language.types.array.foo-bar

http://www.php.net/manual/en/language.types.string.php#language.types.string.parsing

Allerdings sei unbedingt angemerkt, dass die im letzten Link weiter unten beschriebene "complex curly syntax" durchaus ein Einfallstor für Angreifer sein kann. Gerade deswegen ist eval() böse - und nicht nur eval() allein, es gibt noch etliche weitere Funktionen, die das Evaluieren von Code zur Laufzeit durchführen, beispielsweise auch preg_replace() mit dem Modifikator "/e".

Wenn ich deinen Code betrachte, tust du im eval() aber nichts anderes, als exakt eine Codezeile davor ebenfalls schon passiert. Es ist also komplett überflüssig.

Hmm ..., ich hab' mich zum testen/ ausprobieren ja erstmal im Prinzip genau an das Beispiel aus der Doku gehalten, nur mit dem Unterschied, dass meine Variablenwerte halt woanders herkommen.

  1. Wenn ich also nicht eval() verwende, wie mache ich es dann (Cheatas Hinweis serialize() habe ich in dem Zusammenhang nicht begriffen)?

str_replace() beispielsweise.

Die CSS-Vorlage liest du mit file_get_contents() in einen String ein, wendest dann str_replace() auf alle darin enthaltenen Platzhalter an, und ersetzt diese durch die Werte, die du aus deiner INI-Datei erhalten hast, und am Ende packst du den erzeugten String irgendwo passend hin - schickst ihn zum Browser, speicherst ihn direkt auf Festplatte, oder in einen Cache.

Vielen Dank für die sehr verständliche Erklärung!
So werde ich es dann machen. Wie dedlfix ja auch schon geschrieben hat, muss ich dann quasi in einem vorherigen Schritt noch dafür sorgen, meine Platzhalter und mein mehrdimensionales Array in ein übereinstimmendes Format zu bringen, richtig?

Gruß Gunther