Home » Php » How can I store a PHP conditional staement in the database for later use?

How can I store a PHP conditional staement in the database for later use?

Posted by: admin July 12, 2020 Leave a comment

Questions:

In our current application I have a report that contains something like:

if($foo == 3 || $bar > 3) {
    $e = someFunction();
};

but for a different client that same expression might be:

if($foo == 3 || $bar == 5 && $foobar != 9) {
    $e = someFunction();
};

Is there an straight-forward way to store the two different expressions, just the

$foo == 3 || $bar > 3 OR $foo == 3 || $bar == 5

bits in the database (MySQL) so I do not have to hard code all of these rules by client or maintain client versions of the same report. I’m trying to figure out if I can set a variable o replace the conditions. Something like:

$conditions = $row_rsConditions['condition_row']    //Get $foo == 3 || $bar > 3 from the DB and store it as $conditions
if($conditions) {
    $e = someFunction();
};

There could be > 100 different clients and each client could/would have a different set of expressions.
I’m just not sure of the right/best way to do this.

UPDATE:

I think I understand the issues using PHP’s eval() function. But because of the number of possible combinations I am leaning towards using the DB to store the conditions (not sure about using eval() just yet)

Does it make any difference (safer) if there is no user facing interface that writes to the condition field/table? It could be something we manage on our end alone.

How to&Answers:

i would be very careful about storing logic in the database.

  1. you code is no longer all in one place.
  2. logic in the database is unlikely to be under source control
  3. if you change the code and breaks all of that client specific logic, you have to go back into the database and edit it for every client.
  4. other people could have access to the database and could change the code to something malicious.

this might not be the best solution
but i would suggest creating an abstract base class, then inherit from that, a class specific to each client.

Any functions that are customised can be added as a method to the base class, and overridden for client specific implementation.

use a switch statement to instantiate the class based on a client id or name (something that doesn’t change) that you already store in the database.

switch ($client_name) {

case "abc ltd":
   $customlogic = new CustomLogicAbc();
   break;

case "zyx ltd":
   $customlogic = new CustomLogicXyz();
   break;

default: 
   $customlogic = new CustomLogicDefault();
   break;

}

if ($customlogic->doSomething($parm1, $parm2)) {
  // custom logic has been applied
}

Answer:

To elaborate on my comment:

Your last code is nearly what I meant:

$conditions = $row_rsConditions['condition_row'];    //Get "$foo == 3 || $bar > 3"
if(eval("return (" . $conditions . ");")) {
    $e = someFunction();
}

However I will warn you again to remember the risk of doing this.
When you use code from the database it is likely that errors are within.
At least some security check should be done on the data to avoid misuse.

Another option that is a bit more complicated but not that prone to misuse would be to encode the conditions. As it seems that you only compare 2 variables with a value each you could save for each variable something like:

0 !=
1 ==
2 >=
3 <=
4 >
5 <

To save the relation and additionally save the value to which it should be compared. That way there is no direct execution of code that is saved in the database.

Answer:

nobody can tell you how to solve it because nobody knows functional requirements and specific logic of your application… But if time of implementation is important for you you can ofcourse try to use evaluationg of expressions from database , but be careful and use sanitazing of all data from database… There is an example how to make php expressions and execute from database? – you just add more logic because you can have multiply conditions