pistolshrimp
pistolshrimp

Reputation: 1039

Processing a formula comprised of array keys in PHP

I would like to write a function that will process formulas that are comprised of array keys. For example, (1+3+5+7-8)*9 or (1-3+5)/6 and etc Any suggestions?

EDIT: I think it's better to think of this as an excel grid, with field coordinates being the array keys and one of the fields being the formula field (e.g. A1+A2-B2*B3)

Upvotes: 0

Views: 187

Answers (2)

bob-the-destroyer
bob-the-destroyer

Reputation: 3154



function convert_formula($formula, $formula_array) {
    $callback = function($matches) use ($formula_array) {return $formula_array[(int) $matches[0]];};
    $converted = preg_replace_callback("/[0-9]+/", $callback, $formula);
    return eval("return $converted;");
    }

$test_formula = '(3-1) * (3-10)';
$test_formula_array = array(323,67,82,56, 10 => 3);

echo convert_formula($test_formula, $test_formula_array);



Requires PHP 5.3.+ for anon functions. You'll want to first validate the $formula argument to ensure it accepts only numbers and math symbols before you eval it within the function.

Edit: just going by some assumption that this is a tool to instruct students on math and that you already have a pre-built set of formulas to reference... as eval is one of the most dangerous functions of PHP, perhaps you might consider running this client side using javascript. When you build the page, you simply dynamically create a base reference javascript array containing all possible values to be used in the formula. So this way, using javascript's eval function, the client builds and resolves the formula all on their end. That final evaluation is then passed back to your server which then validates the evaluation and gives a final "correct/wrong" response. Just a thought...

Upvotes: 1

Jonah
Jonah

Reputation: 10091

Okay, this one really works.

$input = '0 + 1 + 2 + 3';
$input = preg_replace('/[^0-9\/\+\-\*]/', '', $input);

$array = array(23, 40, 6, 200);

function getAtIndex($i) {
    global $array;
    return isset($array[$i[0]]) ? $array[$i[0]] : 0;
}

$output = preg_replace_callback('/[0-9]+/', 'getAtIndex', $input);

eval('$output = ' . $output . ';');

Edit: now cleans input.

Upvotes: 1

Related Questions