5

Given this example, how would I return the result of the equation rather than the equation itself as a string?

$operator = '+';
foreach($resultSet as $item){
    $result = $item[$this->orderField] . $operator . 1;
    echo $result;
}
BenTheDesigner
  • 1,954
  • 3
  • 17
  • 21
  • 1
    What is the real case led you to this question? – Your Common Sense Mar 31 '10 at 10:35
  • I needed to swap items in an array but maintain their keys and values. $item[$this->orderField] would be the current item, +/- 1 would be the item it would swap positions with. I have written an array_swap function, and combined with reko_t's method it produces something similar to array([1]=>'1', [0]=>'0', [2]=>'2') from array([0]=>'0', [1]=>'1', [2]=>'2'). – BenTheDesigner Apr 01 '10 at 09:26

5 Answers5

17

You could make functions that wrap the operators, or for simplicity just use the bc extension:

$operator = '+';
$operators = array(
  '+' => 'bcadd',
  '-' => 'bcsub',
  '*' => 'bcmul',
  '/' => 'bcdiv'
);

foreach($resultSet as $item){
    $result = call_user_func($operators[$operator], $item[$this->orderField], 1);
    echo $result;
}
John Carter
  • 53,924
  • 26
  • 111
  • 144
reko_t
  • 55,302
  • 10
  • 87
  • 77
  • 1
    Use an arbitrary precision math library to perform regular math? Looks kind of quirky... – Álvaro González Mar 31 '10 at 14:51
  • 2
    Develop with extensibility in mind Alvaro... Who says the same function may not need to perform precision mathematics? – BenTheDesigner Apr 01 '10 at 09:34
  • The performance in a situation like this is absolutely negligible in most cases. Ever heard of the saying premature optimization is the root of all evil? ;) Write clean, easy-to-understand and maintainable code and optimize if necessary. – reko_t Sep 03 '11 at 12:50
7

To achieve exactly that, you can use create_function

$operator = '+';
$func = create_function('$a,$b', "return \$a $operator \$b;");
foreach($resultSet as $item){
    $result = $func($item, 1);
    echo $result;
}

A cleaner solution is possible with lambdas (php5.3 required)

$func = function($a, $b) { return $a + $b; };
foreach($resultSet as $item){
    $result = $func($item, 1);
    echo $result;
}

See also array_sum, array_reduce

Advanced example with array_reduce and lambdas

$ary = array(
    array('foo' => 1, 'bar' => 91),
    array('foo' => 2, 'bar' => 92),
    array('foo' => 3, 'bar' => 93),
    array('foo' => 4, 'bar' => 94),
    array('foo' => 5, 'bar' => 95),
);

$sumOfFoos = array_reduce($ary, 
    function($val, $item) { return $val + $item['foo']; } 
);
$sumOfBars = array_reduce($ary, 
    function($val, $item) { return $val + $item['bar']; } 
);

The main point is, that instead of 'variable operators' (which is not possible in php), you should rather use variable functions (which is possible and much more flexible).

user187291
  • 53,363
  • 19
  • 95
  • 127
2

You can use eval(), but it's generally a bad idea, since it's a major potential security hole (be careful you're not allowing visitors to run arbitrary code!).

It can also result in hard to maintain code.

John Carter
  • 53,924
  • 26
  • 111
  • 144
2

Quick answer is eval(). However, in this precise example I would just hard-code the possible operations:

<?php

$operator = '+';
foreach($resultSet as $item){
    switch($operator){
        case '+':
            $result = $item[$this->orderField] + 1;
            break;
    }
    echo $result;
}

?>
Álvaro González
  • 142,137
  • 41
  • 261
  • 360
1

Use the eval function of PHP: http://php.net/manual/en/function.eval.php

$operator = '+';
foreach($resultSet as $item){
    $result = $item[$this->orderField] . $operator . 1;
    eval("\$result = \"$result\";");
    echo $result;
}
Hannes de Jager
  • 2,903
  • 6
  • 37
  • 57