[PHP/MySQL] Scriptcode auswerten
Verfasst: 30.08.2011, 16:31
Hallo ich habe eine SQL-Datenbank auf die ich per PHP/MySQL zugreife. In der Datenbank gibt es Einträge, die Scriptcode in Textform enthalten. Der Scriptcode ist keine gängige Sprache (es gibt keine Compiler/Interpreter etc dafür).
Solche Skripte haben die Form:
<scriptexpr> <scriptexpr> ...
Also eine beliebige Anzahl von Skriptanweisungen.
Eine Skriptanweisung hat die Form:
<command><N> <params>;
<command> ist ein Befehlsname.
<N> ist entweder nicht vorhanden (was für 1 steht) oder eine Zahl von 2-4. Dies ist die Anzahl der Parameter.
<params> ist eine Liste von Parametern, die mit Kommata getrennt sind (Integer oder String in einfachen Hochkommata).
Dazu kommt eine Hand voll von Spezialbefehlen der Form:
<command> { <scriptexpr> }
<command> ist ein Befehlsname.
<scriptexpr> ist eine Skriptanweisung der oben genannten Form.
Was ich nun tun möchte ist, den Skriptcode aus einer Datenbank lesen (ist kein Problem) und das Skript in PHP "ausführen". Das ich dafür eine Art Mini-Interpreter brauche ist mir bewusst. Die Daten auf denen die Skripte angewendet werden sind in meinen PHP Skripten integriert.
Meine Frage ist nun wie ich die Auswertung der Skripte bzw. Befehle am besten realisieren könnte. Zur Info: Es gibt an die 100 Befehle.
Eine riesiges switch-case mit allen Befehlen erscheint mir nicht geeignet. In C++ gesprochen: Eine Art std::map mit KEY = Befehlsname und VALUE = Funktionspointer wäre meiner Meinung nach schon etwas angenehmer, wobei ich nicht weiß ob und wie sowas in PHP funktioniert. Um 100 Funktionen für jeden Befehl werde ich wohl auch nicht so recht drum rum kommen.
Ich würde gern erstmal wissen, wie man das ganze vielleicht am besten umsetzen könnte. Die Befehle darf man sich nicht als einfache Operationen auf Variable vorstellen.
Ein Beispiel wäre z.B. der Befehl
Str,1;
Dieser erhöht die Stärke eines Charakters um 1. In den PHP-Skripten gibt es dann irgendwo die Variable $Str oder ein Array mit dem Index 'Str', die bei diesem Befehl um 1 erhöht werden muss. Es gibt aber noch viele weitere Befehle, die ganz verschiedene Werte ändern. Letztlich ändern aber alle Befehle nur Werte. Daher dachte ich schon an eine Art Substitution. Beispiel:
Str,x; wird zu $Str = $Str + x;
Das ganze könnte man dann z.B. mit eval() ausführen.
Was ich allerdings noch vergessen habe. Im oben genannten Scriptcode können auch noch if-Anweisungen vorkommen, allerdings ohne else oder elseif. Die Form ist dabei wie in C++, allerdings gibt es im Skript selbst keine Variablen, sondern nur vordefinierte Abfragefunktionen.
Beispiel:
if(getitemcount(356) > 1) { Str,1; }
Das bedeutet z.B., dass die Stärke um 1 erhöht wird, wenn ich vom Item mit der ID 356 mindestens 2 Items besitze.
Sprich ich muss ifs auch berücksichtigen und die Abfragefunktionen ebenfalls in PHP zur Verfügung stellen. Diese könnte ich in PHP aber ggf. genauso wie im Skript nennen um das eval() zu erleichtern. Das if sollte ja theoretisch auch so direkt evaluierbar sein (mit Ausnahme der logischen Operatoren, die im Skript & oder | sind und in PHP and bzw. or).
Also grundsätzlich tendiere ich zu leichter Anpassung bzw. Substitution mit anschließendem eval(). Wäre aber über Hinweise und Meinungen dankbar. Auch in Hinblick auf den Fummelkram mit den Eingabestings. Mir fällt in dem Zusammenhang z.B. strtok ein aber vielleicht gibt es da noch schönere Dinge. Glaub für regexes gabs da in PHP auch paar Sachen. Will nicht alles händisch zusammenbasteln müssen.
Solche Skripte haben die Form:
<scriptexpr> <scriptexpr> ...
Also eine beliebige Anzahl von Skriptanweisungen.
Eine Skriptanweisung hat die Form:
<command><N> <params>;
<command> ist ein Befehlsname.
<N> ist entweder nicht vorhanden (was für 1 steht) oder eine Zahl von 2-4. Dies ist die Anzahl der Parameter.
<params> ist eine Liste von Parametern, die mit Kommata getrennt sind (Integer oder String in einfachen Hochkommata).
Dazu kommt eine Hand voll von Spezialbefehlen der Form:
<command> { <scriptexpr> }
<command> ist ein Befehlsname.
<scriptexpr> ist eine Skriptanweisung der oben genannten Form.
Was ich nun tun möchte ist, den Skriptcode aus einer Datenbank lesen (ist kein Problem) und das Skript in PHP "ausführen". Das ich dafür eine Art Mini-Interpreter brauche ist mir bewusst. Die Daten auf denen die Skripte angewendet werden sind in meinen PHP Skripten integriert.
Meine Frage ist nun wie ich die Auswertung der Skripte bzw. Befehle am besten realisieren könnte. Zur Info: Es gibt an die 100 Befehle.
Eine riesiges switch-case mit allen Befehlen erscheint mir nicht geeignet. In C++ gesprochen: Eine Art std::map mit KEY = Befehlsname und VALUE = Funktionspointer wäre meiner Meinung nach schon etwas angenehmer, wobei ich nicht weiß ob und wie sowas in PHP funktioniert. Um 100 Funktionen für jeden Befehl werde ich wohl auch nicht so recht drum rum kommen.
Ich würde gern erstmal wissen, wie man das ganze vielleicht am besten umsetzen könnte. Die Befehle darf man sich nicht als einfache Operationen auf Variable vorstellen.
Ein Beispiel wäre z.B. der Befehl
Str,1;
Dieser erhöht die Stärke eines Charakters um 1. In den PHP-Skripten gibt es dann irgendwo die Variable $Str oder ein Array mit dem Index 'Str', die bei diesem Befehl um 1 erhöht werden muss. Es gibt aber noch viele weitere Befehle, die ganz verschiedene Werte ändern. Letztlich ändern aber alle Befehle nur Werte. Daher dachte ich schon an eine Art Substitution. Beispiel:
Str,x; wird zu $Str = $Str + x;
Das ganze könnte man dann z.B. mit eval() ausführen.
Was ich allerdings noch vergessen habe. Im oben genannten Scriptcode können auch noch if-Anweisungen vorkommen, allerdings ohne else oder elseif. Die Form ist dabei wie in C++, allerdings gibt es im Skript selbst keine Variablen, sondern nur vordefinierte Abfragefunktionen.
Beispiel:
if(getitemcount(356) > 1) { Str,1; }
Das bedeutet z.B., dass die Stärke um 1 erhöht wird, wenn ich vom Item mit der ID 356 mindestens 2 Items besitze.
Sprich ich muss ifs auch berücksichtigen und die Abfragefunktionen ebenfalls in PHP zur Verfügung stellen. Diese könnte ich in PHP aber ggf. genauso wie im Skript nennen um das eval() zu erleichtern. Das if sollte ja theoretisch auch so direkt evaluierbar sein (mit Ausnahme der logischen Operatoren, die im Skript & oder | sind und in PHP and bzw. or).
Also grundsätzlich tendiere ich zu leichter Anpassung bzw. Substitution mit anschließendem eval(). Wäre aber über Hinweise und Meinungen dankbar. Auch in Hinblick auf den Fummelkram mit den Eingabestings. Mir fällt in dem Zusammenhang z.B. strtok ein aber vielleicht gibt es da noch schönere Dinge. Glaub für regexes gabs da in PHP auch paar Sachen. Will nicht alles händisch zusammenbasteln müssen.