Forum Moderators: coopster

Message Too Old, No Replies

Create an IF condition dynamically

On the fly, how? I'm stuck here

         

explorador

12:34 pm on Oct 27, 2023 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Hi everyone, I need to create an IF condition dynamically. I will interpret and validate certain user input, and then produce a code style condition for an IF.

I can easily do that, even validate it before applying it, the problem I see is turning the final (parsed and then re-generated) condition to the code. Like... creating this string:

name == "Luke" && age=30 && country="Jamaica"

Yes, can do that, that's exactly and literally the if condition, but how can I turn it into pure code?

Let's explain, this is hand written code:
if (name == "Luke" && age=30 && country="Jamaica"){
etc
}


I need this:
if (-dynamically generated condition-){
etc
}


1. I can easily generate a string with the condition built in code mode, but naturally, it won't be interpreted.
2. I could generate the string and then incorporate an EVAL there, but... not all servers have eval enabled for security reasons.




$condition=(name == 'Luke' && age=30 && country='Jamaica');

if ($condition){
etc
}


3. Questions and answers around the web point to dynamically generate conditions using parenthesis without quotes like shown above, I can do that too, but then again that's human written code inside the script, it won't work, unless I find a way to convert A STRING to "non quotes string". It's a bit difficult to explain/understand if you are not familiar with the challenge, but once you have faced this you see it right away. Any ideas how to pass the value of a string and turn it into a value-that-is-not-using-quotes-as-string?

Juniya

8:42 am on Oct 30, 2023 (gmt 0)

10+ Year Member Top Contributors Of The Month



Here's an approach you could use in a language like PHP without using eval:

Parse the Condition String: Break down the condition string into its constituent parts (variables, operators, and values).

Use Conditional Functions: Instead of directly interpreting a string as code, create functions that take parts of the condition and evaluate them. For example, you might have a function that takes a variable name, an operator, and a value, and then returns the result of that comparison.

Call Functions Dynamically: You can use the parsed condition parts to call these functions dynamically. In PHP, you might use call_user_func or similar.

Example:

// Define a list of allowed operators for security reasons
$allowedOperators = ['==', '!=', '<', '>', '<=', '>='];

// This is the condition string you've dynamically generated
$conditionString = "name == 'Luke' && age == 30 && country == 'Jamaica'";

// You would parse this string into an array of conditions
$conditions = parseConditionString($conditionString);

// Initialize a variable to keep track of the overall condition validity
$isValid = true;

foreach ($conditions as $cond) {
// Here you would split each condition by spaces, this is very simplified
list($variable, $operator, $value) = explode(' ', $cond);

// Security check to make sure only allowed operators are used
if (!in_array($operator, $allowedOperators)) {
// Handle error: operator not allowed
$isValid = false;
break;
}

// Assuming your variables are in an associative array like $_POST, $_GET, etc.
$variableValue = $yourVariableArray[$variable];

// Dynamically call a function that evaluates the condition
$result = call_user_func('evaluateCondition', $variableValue, $operator, $value);

// If any condition fails, the whole statement should fail
if (!$result) {
$isValid = false;
break;
}
}

// Now you have a boolean value in $isValid that determines if your conditions are met
if ($isValid) {
// Your code here
}

// Function to evaluate a single condition
function evaluateCondition($var, $op, $val) {
switch ($op) {
case '==': return $var == $val;
case '!=': return $var != $val;
case '<': return $var < $val;
case '>': return $var > $val;
case '<=': return $var <= $val;
case '>=': return $var >= $val;
default:
// Handle invalid operator
return false;
}
}

// Function to parse the condition string into an array of individual conditions
function parseConditionString($str) {
// This is a placeholder; you'll need a more complex parser
// that can handle the syntax and nuances of your condition strings
return explode('&&', $str);
}

parseConditionString is a placeholder for whatever parsing logic you need to implement to correctly interpret the condition string. The security check is crucial to avoid injection attacks.

This way, you're not directly executing code from a string, but you are dynamically determining the outcome based on the string's content in a controlled manner.

explorador

3:03 pm on Oct 30, 2023 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Juniya: This way, you're not directly executing code from a string, but you are dynamically determining the outcome based on the string's content in a controlled manner.

I really appreciate your time explaining this how-to Juniya, and that's is exactly what I'm doing right now, and yes it works.

Just as you describe I take a string user generated input like "name == Mary && age ==25", then I analyze it/parse it/explode it, to use a set of switch + foreach to analyze the analyzed-results and matches (not BD matches but the condition matches). Yes, it works, and additional points for you for the effort actually writing down the explanation, it's not easy.

While this is working for me (started coding it exactly oct 27), it gets complicated: there is no way to know how many conditions are sent in the string (yes, that's not an entire issue, as N number of conditions can be processed via condition+loops; the problem is X number of conditions combined with diff comparisons COMBINED with multiple "groups" of operators. AND operators are easy, OR are also easy (both, separated), but once the query gets complicated, the analysis and parsing becomes really difficult, like:

1. name == Mary && age==25 (easy) 1+1
2. name == Mary || age==25 (easy) 1 (at least 1)
3. name == Mary && age==25 || name == Sigrid && age == 30 (it gets complicated, because the || doesn't represent a simple OR, but instead, it represent the separation of a group/set of comparisons/evaluators), and it could be as complex as: name == Mary && age==25 || name == Sigrid && age == 30 || lastname == Wilkings && status !== single (at least 1+1 out of 3)

It's doable, I think, I just don't see it clearly in my head yet, I just might need some brain rest and more coffee, so, before killing some brain cells I wondered if there is a better way that I didn't know about.

Thanks!

* It seems (by now) what you describe (and what I have partially complete) it's the only way.

explorador

5:23 pm on Oct 30, 2023 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The primary tests have been working for multiple (unlimited) conditioning, what I still have to add is as described previously: multiple groups, as on specific situations the OR splits the conditions into multiple groups that include one or multiple and.