PHP использует строку в качестве оператора

#php #expression #operator-keyword #evaluate

#php #выражение #оператор-ключевое слово #вычислять

Вопрос:

Допустим, у меня есть строка, $char. $char == "*".

У меня также есть две переменные, $ a и $ b, которые равны «4» и «5» соответственно.

Как мне получить результат $a $char $b, ie 4 * 5 ?

Спасибо 🙂

Ответ №1:

Вы можете использовать eval() , как предложено @konforce, однако самым безопасным маршрутом было бы что-то вроде:

 $left = (int)$a;
$right = (int)$b;
$result = 0;
switch($char){

  case "*":
    $result = $left * $right;
    break;

 case " ";
   $result = $left   $right;
   break;
// etc

}
  

Комментарии:

1. это ответ, который я искал 🙂

Ответ №2:

самый безопасный метод — это конструкция switch:

 function my_operator($a, $b, $char) {
    switch($char) {
        case '=': return $a = $b;
        case '*': return $a * $b;
        case ' ': return $a   $b;
        etc...
    }
}
  

Комментарии:

1. да … люди отвечают слишком быстро!

2. если оператор является, = ваш код выдаст sum количество операндов. Не должно ли быть break ?

3. ‘=’ ничего бы не сделало в этом случае, если бы $ a не был передан в качестве ссылки. В противном случае присваивание будет потеряно, как только функция вернется. Это просто пример.

4. @ShaktiSingh Нет необходимости в break , когда есть return

Ответ №3:

Самый простой, но и самый опасный метод заключается в использовании eval .

 $c = eval("return $a $char $b;");
  

Комментарии:

1. Я бы предпочел не использовать eval, поскольку значения поступают из пользовательского ввода.

2. @konforce: Наконец-то все, что нам осталось использовать в продакшене, — это то, почему мы предлагаем eval

3. @Fela, вы должны всегда проверять вводимые пользователем данные, используете вы eval или нет. Если вы проверяете, что $a и $b являются правильными числами и это $char правильная операция, то eval это будет безопасно. Тем не менее, я бы все равно не использовал eval на общедоступном сайте.

4. если это локальный проект, нет причин не использовать eval .

5. Я не использую eval, я использую переключатели с разными операторами. Весь пользовательский ввод, конечно, очищается.

Ответ №4:

Другим способом избежать создания переключателя / регистра может быть:

 <?php 
// Doesn't matter if $a and $b are integers or strings
$a = 100;
$b = 1000;
$operator = ">";

$operations = [
  '='  => $a == $b,
  '>'  => $a > $b,
  '>=' => $a >= $b,
  '<'  => $a < $b,
  '<=' => $a <= $b,
  '<>' => $a <> $b,
];

// It will get the value of $a > $b and the result will be false
$operations[$operator]
?>
  

Наконец, если вы предпочитаете, вы можете переместить массив $operations в функцию, чтобы улучшить читаемость кода.

 <?php 
// Doesn't matter if $a and $b are integers or strings
$a = 100;
$b = 1000;
$operator = ">";

// It will get the value of $a > $b and the result will be false
$result = getOperationResult($a, $b, $operator);

function getOperationResult(string|int $a, string|int $b, string $operator): bool
{
    $operations = [
      '='  => $a == $b,
      '>'  => $a > $b,
      '>=' => $a >= $b,
      '<'  => $a < $b,
      '<=' => $a <= $b,
      '<>' => $a <> $b,
    ];

    return $operations[$operator];
}
?>
  

Ответ №5:

взгляните на функцию eval(). вам нужно будет создать соответствующую команду php и запустить внутри eval(), чтобы извлечь результат.

Ответ №6:

Вы можете использовать eval однако я бы не советовал использовать eval .

Если есть оператор case, то вы должны проверить, какой оператор используется перед использованием

 switch($char)
{
  case '*':
    $result= $a * $b;
    break;

  case ' ':
    $result= $a   $b;
    break;
}
  

Комментарии:

1. Да, я собираюсь использовать этот вариант. Спасибо 🙂

Ответ №7:

 <?php
$a = 'alex';
$b = "alex";
$c = "==";
function abc($a,$b,$c){
  $d = 'return ($a '.$c.' $b) ? true : false;';
  return eval($d);
}
if(abc($a,$b,$c)){
  echo "condition true";
}else{
  echo "condition false";
}
// echo $e;
?>
  

Комментарии:

1. пожалуйста, объясните ваше решение