1

I am trying to use an operator as a variable.

$num1 = 33;
$num2 = 44;
$operator = "+";
$answer = ($num1.$operator.$num2);

It prints "33+44" instead of 77.

Or,

$operators = array(
   "plus"=>"+", 
   "minus"=>"-",
   "times"=>"*", 
   "div"=>"/"
  );

I want to be able to use as: $answer = $num1.$operators["plus"].$num2;

How can I achieve this without using "if" statement?.

$answer = ($operator == "+") ? $num1 + $num2 : 0;
3
  • 2
    You can't do this without conditions, unless you use eval Commented Aug 18, 2014 at 6:48
  • 1
    This is doable without using EVAL. Please see my answer stackoverflow.com/a/25357745/199593 Commented Aug 18, 2014 at 6:59
  • Related question. Commented Aug 18, 2014 at 7:18

4 Answers 4

4
    $num1 = 33;
    $num2 = 44;
    $operator = "+";
    eval("\$result = $num1 $operator $num2;"); 
    echo $result;

Caution The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.

Sign up to request clarification or add additional context in comments.

Comments

3

On the user-land

Think about things that you're trying to achieve. Why don't create fixed-code closures? You may easily do it with:

$operators = array(
   "plus"=>function($x, $y)
   {
      return $x+$y;
   }, 
   "minus"=>function($x, $y)
   {
      return $x-$y;
   },
   "times"=>function($x, $y)
   {
      return $x*$y;
   }, 
   "div"=>function($x, $y)
   {
      return $x/$y;
   }
  );

//in PHP 5.5:
$result = $operators['plus']($num1, $num2);
//in PHP<5.5:
//$result = call_user_func_array($operators['plus'], [$num1, $num2])

Now you have two things: first, it's still dynamic code - and you may use it in expressions. Next, you're safe in terms of code evaluation - because you've defined the code by yourself. This approach also has advantage - you may define desired behavior as you wish. For instance, raise an exception for "div" operator if second operand is zero.

"Easy" way

I'll notice this only to explain why this isn't a right way. You may use eval(). It's like:

eval('$result='.$num1.$operators['plus'].$num2.';');

And then your result would be stored in $result variable. It is about "easy" way, but not "right" way. The problem is - it is unsafe. Just think about it - you're executing some code, which is dynamic. If your code has nothing to do with user input, it may be applicable - in case, if you're checking your operands and operator before. But I still recommend to think twice before applying it.

If evaluation still needed

Then I recommend to look to some existing implementations. Here are some links:

Comments

2

You can try to use BC Math functions. This example works with php 5.5:

$num1 = 33;
$num2 = 44;
$operator = '+';
$funcs = array(
    '+' => 'bcadd',
    '-' => 'bcsub',
    '/' => 'bcdiv',
    '*' => 'bcmul',
    );

$answer = $funcs[$operator]($num1, $num2); // 77

Comments

0

I question why you want to pass the arithmetic operator as a string in the first place, but here's a way to do it without using an if statement:

function fancy_math($num1 = 0, $num2 = 0, $operator = '+')
{
    switch ($operator) {
        case 'minus':
        case '-':
            return $num1 - $num2;
            break;

        case 'times':
        case '*':
            return $num1 * $num2;
            break;

        case 'div':
        case '/':
            return ($num2 !== 0) ? $num1 / $num2 : 'Error: divide by zero';
            break;

        default:
            return $num1 + $num2;
            break;
    }
}

And then call it like this:

$answer = fancy_math($num1, $num2, $operator);

Note you can pass 'minus' or '-' (etc) as the $operator as it will accept both. If you don't pass an $operator it will assume 'plus' or '+' automatically.

8 Comments

Return a string or number in case of "div"? Type-safe comparison while nowhere before types are checked? Actually, not good ideas
The whole thing is in the category of "not good ideas." I could have just let the potential divide by zero happen like you did. Otherwise, our two solutions attack the problem in the same fashion. Mine is dead basic and runs anywhere. Your's requires 5.5 or the clumsy call_user_func_array().
Actually, usage of PHP<5.5 is also a bad idea
Yes, and it sucks to drive anything less than the current model year car too. Reality is most of the cars on the road aren't current year; most of the PHP hosts around aren't 5.5 either.
Reality is so that PHP versions have nothing to do with cars. Usage of older versions is at least non-safe. Same goes for most software. If there are no reasons to use lower versions, don't use it (and in reality there are no such reasons, because BC were broken only starting from 5.2). But no matter the version. Returning string in context of numeric function is just wrong.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.