Supertoller Wrapper für Lua in PHP

multimolti

Erfahrenes Mitglied
Hallo! (langer Text, wichtige Teile sind fett)

Ich weiß nicht, ob der Titel so viel sagt, daher beschreibe ich noch mal genau was ich möchte:
Person A hat ein großes CMS in PHP und möchte Person B, der aber nicht vertraut wird, die Möglichkeit geben, das CMS (das aber auf den Servern von A läuft) mit eigenen Scripts zu erweitern. Da es per PHP viel zu gefährlich wäre habe ich eine sichere Lua-Sandbox gebaut, die das Script von B ausführen kann ohne dass irgendwas kaputt gehen kann (kein IO, Laufzeitlimitierung, Speicherlimitierung, etc.). Soweit schön und gut, von PHP aus kann ich sagen "Starte tolles_script.lua und gib mir das Ergebnis", dann wird tolles_script.lua mit bestimmten Parametern ausgeführt und die Rückgabewerte an PHP zurückgegeben.

Das ganze System ist aber noch recht "unpraktisch". Von PHP aus hat man nur die Möglichkeit, das Script aufzurufen, außerdem wird bisher nicht sichergestellt, dass auch der richtige Datentyp reingeht. Und generell ist es nervig, die in Lua geschrieben Methode so aufrufen zu müssen (schematisch):
PHP:
// code, return type
$script = new tcc_Lua_Script("function verdoppeln(x) return 2*x end", "int");
// parameter
$script->run(17);
$result = $script->getResult(); // $result = 34
Das funktioniert, aber wenn ich es irgendwie hinbekommen könnte dass ich einfach tippe:
PHP:
$result = _lua(verdoppeln(17)); // $result = 34
wäre das deutlich schöner und performanter =)

Habt ihr irgendeine Idee, wie ich das hinbekommen kann? Also dass sich der Aufruf einer Lua-Methode gefühlt kaum von dem einer PHP-Methode unterscheidet? (Die Funktion "verdoppeln" wäre bei Beispiel 2 in der MySQL-DB definiert).

Danke!!
 
Zuletzt bearbeitet:
Also ich find den Ansatz nicht so schön, muss ich gestehen...
Ich würde PHP zulassen, das ganze aber nur unter der Voraussetzung, dass bestimmte Funktionen nicht erlaubt sind.
Mit den Tokenizer Funktionen kann man den Plugin Code zerlegen und prüfen welche Funktionen erlaubt sind, da hier schon eine Misstrauensbasis steht, sollte man eventuell sogar mit einer Whitelist arbeiten, und dann den Code ausführen oder zurückweisen mit Fehlermeldungen.
 
Hatte ich mir auch gedacht, leider lautet der Auftrag des Chefs "Lua Wrapper" und nicht "PHP Plugin Wrapper" ;-)

Außerdem soll der Kram evtl. später noch auf Java und C ausgeweitet werden, weshalb das Problem eh herrscht. Eine Whitelist habe ich in Lua natürlich schon drin, das klappt auch alles soweit, nur das Aufrufen aus PHP heraus ist etwas unschön. Grade eben ist mir etwas mit den __call und __callStatic-Funktionen von PHP eingefallen, damit könnte man ganz schön arbeiten, leider ist die __callStatic aber nur in PHP 5.3 definiert und ich muss 5.2 nutzen =(
 
Erstens das und zweitens hat mein Chef den probiert und der soll so schlecht und verbuggt sein dass der nicht einsetzbar ist. Daher eine eigene Lösung.
 
Ich glaube das hier macht das, was du suchst ;)
(musst du noch ein bisschen anpassen, damit ich hier nicht alles mache :P )
PHP:
class lua{
  private $con;
  private $db;
  public function lua($host,$user,$pass,$db){
    $this->con = mysql_connect($host,$user,$pass);
    $this->db   = mysql_select_db($db,$this->con);
  }
  public function __call($name, $arguments) {
        $result = mysql_query("SELECT * FROM `functions` WHERE `function_name` = '".mysql_real_escape_string($name, $this->con)."'", $this->con);
        if( mysql_num_rows($result) == 1 ){
          $row = mysql_fetch_assoc($result);          
          eval(str_replace("Arguments",$arguments,$row["function_code"])); //zwar nicht schön aber scheint hier sicher zu sein, da nur du Daten in die Datenbank eintragen kannst
        }
        else
          trigger_error("Undefined function $name.", E_USER_ERROR);
    }
}

Würde dann so funktionieren
PHP:
$lua = new lua("localhost","user","password","db");
$lua->funktionsName();
 
Danke für die Antworten, ich glaube ich habe eine gute Lösung gefunden, die auch das mit den Datentypen überprüft (intern). Das ganze sieht jetzt etwa so aus:
PHP:
// initialize and set script source
$l = new LuaWrapper(new FetchScriptMySQL());

// call Lua function
$result = $l->verdoppeln(new Int(17));

// show result and output
echo $result->getValue();
echo "<br>---";
var_dump($result);
Man erstellt einen neuen Wrapper mit Klasse, die die Daten aus MySQL holt (könnten auch z.B. aus TXT oder <form> kommen), dann führt man die Funktion typsicher aus (das mit new Int(17)), bekommt ebenfalls ein Objekt (in diesem Fall Int) zurück und kann das dann verwenden. Ausgabe sieht so aus:
Code:
34
---
object(Int)[9]
  protected 'value' => int 34
  protected 'force' => boolean false

Gefällt mir sehr gut und dem Chef hoffentlich auch =)
 
Zurück