Ben: Logische Operatoren in Variablen speichern

Hallo zusammen

Ich möchte gerne logische Operatoren in Variablen speichern. Hintergrund ist folgender:

Der Admin der Seite sollte selber gewisse Bedingungen festlegen können, nach denen dann die eingegebenen Werte überprüft werden. Z.B. mit Geld und Zinsen: ist der eingegebene Betrag kleiner als 500.-, gibt es 2% Zins, ist er kleiner als 1000.- gibt es 2,5% oder ist er grösser als 10000.- 4%. Diese Bedingungen möchte ich flexibel in die DB speichern und dann die if-Konstrukte aus der DB zusammenbasteln.

Hat jemand eine Idee wie man das am besten löst?

Danke und Gruss
Ben

  1. Hallo,

    so wie ich deinen Beitrag lese möchtest du gerne auf Werte beliebige logische Ausdrücke anwenden, um jedem Wert einen anderen zuzuordnen.

    Zuerst wäre dabei interessant, ob du dich nur auf numerische Werte beschränken willst. Außerdem ist wichtig, ob die Operatoren ==, >, >=, <, <= reichen oder ob du auch noch unäre Funktionen wie die Negation benötigst. Ich gehe erstmal davon aus, dass das beides nicht der Fall ist - sonst wirds komplizierter ;-)

    Der allgemeine Ansatz wäre: Einen Parser schreiben, der den vom Benutzer eingegebenen Ausdruck in eine interne Datenstruktur überführt; die terminalen Symbole wären dann der Wert selber (bei dir der Geldbetrag) oder eingegebene Konstanten (in deinem Beispiel 500, 1000 oder 10000). Üblicher Weise wäre das ein Baum, der sich jedoch auch in Kommandos einer abstrakten Stackmaschine überführen ließe. Je nachdem müsstest du dann einen Baum in der Datenbank speichern, was relativ unschön aussieht, oder eine ASM-artige Befehlsfolge, was auch nicht viel besser ist. Dieser Ansatz besticht durch Kompliziertheit aber auch Flexibilität und Ästhetik :-)

    Einfacher in deinem Fall wäre, es so hinzubiegen, dass PHP das Parsen und die Auswertung des Ausdrucks übernimmt. Angenommen, jemand gibt ein:

    (Wert > 10 AND Wert < 20) OR (Wert > 50 AND Wert < 60)

    Dann müsstest du nur noch vor der Auswertung 'Wert' gegen den zu überprüfenden Wert, 'AND' gegen '&&' und 'OR' gegen '||' ersetzen und vor die Zeichenkette vor Ausführung von eval noch ein 'return ' hängen.

    Nachteil: Du hast alle Risiken und Nebenwirkungen der eval()-Funktion. Dazu zählen Sicherheitslücken und Performanceschwächen, welche du gesondert behandeln musst. Eine saubere lexikographische Analyse sollte jedoch meiner Meinung nach ausreichend sein.

    Diese Lösung besticht durch Einfachheit und Flexibilität - aber für die Praxis ist sie nicht so gut geeignet.

    Wenn du nur Wertebereichsintervalle Werten zuordnen willst, solltest du diese Funktion lieber anders speichern, z.B. in einer Relation mit den Attributen wert_von, wert_bis, zugeordneter_wert.

    Die Lösung ist einfach, sicher, schnell - aber leider nicht wirklich flexibel.

    Pass in jedem Falle darauf auf, dass die Zuordnungen auf dem ganzen Wertebereich definiert sind, d.h. dass alle möglichen Werte auch eine Zuordnung erhalten. Außerdem sollten die Mengen der Zahlen, welche die Ausdrücke erfüllen, disjunkt sein, d.h. ein Wert darf nie bei zwei Ausdrücken wahr sein (auch wenn das nur dann wirklich problematisch ist wenn die Funktion nicht injektiv ist blabla). Das lässt sich ohne größerem Aufwand nur bei der dritten Methode, wo man die Intervalle angibt, überprüfen.

    Noch einfachere Methoden sind mir nicht bekannt - vielleicht hat ja schonmal jemand eine Bibliothek für genau dieses Problem entworfen?

    Nun musst du wissen, wie viel du dir zutraust. Falls dir das alles nicht so zusagt, würde ich dir die zweite Lösung empfehlen. Solange es keine Sicherheitslücken gibt, lässt sich auf die Tour am schnellsten eine funktionierende Lösung zusammenbasteln.

    Viele Grüße,
      Johannes