@GeKskill

Строка из БД как условие сравнения в if?

В базе записаны операторы сравнения в виде строк : "<=", "=" и т.д Как их подставить в if?
  • Вопрос задан
  • 101 просмотр
Решения вопроса 2
v3shin
@v3shin
Веб-шаман
Можно как-то так, в зависимости от вашего кода и нужд:
if ($row['compareSign'] === '<=') {
    return $a <= $b;
} elseif ($row['compareSign'] === '>') {
    return $a > $b;
}
Ответ написан
Комментировать
class RuleHelper
{
    /**
     * Checks rule for value
     * @param mixed $value value to check
     * @param string $rule rule for checking
     * @param array $args arguments for rule
     * @return bool
     */
    public static function check($value, string $rule, array $args): bool
    {
        switch($rule) {
            case '=':
                if((string)$value === (string)$args[0]) {
                    return true;
                }
                break;
            case '!=':
                if((string)$value !== (string)$args[0]) {
                    return true;
                }
                break;
            case '>':
                if($value > $args[0]) {
                    return true;
                }
                break;
            case '>=':
                if($value >= $args[0]) {
                    return true;
                }
                break;
            case '<':
                if($value < $args[0]) {
                    return true;
                }
                break;
            case '<=':
                if($value <= $args[0]) {
                    return true;
                }
                break;
            case 'between':
                if($value >= $args[0] && $value <= $args[1]) {
                    return true;
                }
                break;
            case 'in':
                if(in_array($value, $args[0])) {
                    return true;
                }
                break;
            case 'not in':
                if(!in_array($value, $args[0])) {
                    return true;
                }
                break;
            case 'between strict':
                if($value > $args[0] && $value < $args[1]) {
                    return true;
                }
                break;
        }

        return false;
    }
}

RuleHelper::check($operand1, $row['compareSign'], $operand2);
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
Вообще можно использовать eval() (хотя я бы не стал), но по хорошему это лечится пенделем проектировщику такого чудесного функционала.
Ответ написан
@ksnk
У меня где-то использовался `язык фильтров` - строка с условиями, которую удобно вписывать в область фильтра в столбик таблицы с данными. Постим на сервер - получаем фильтрованное.
Сама строка условий выглядит примерно так
count=2,<2;count=3,<300,>44
условия соединяются запятой, по AND, точкой с запятой - по OR, у OR более низкий приоритет. Операция сравнения соединяет 2 операнда, если один из операндов пустой - берется "сравниваемое значение", если число - то число, иначе ищем во внешних "данных".
Если записать строку на php - будет что-то вроде
$current=45; // значение, которое сравниваем
$data=['count'=>3]; // внешние данные
if( ($data['count']==2 && $current<2) || ($data['count']==3 &&$current>44 && $current<300)){
    // ...
}

Удобно в языке то, что парсер его компактен и легко допиливается напильником по месту.
function evaluate($current,$cond,$data=[]){
    $res=false;
    foreach(explode(';',$cond) as $or){ //or
        foreach(explode(',',$or) as $and) { //and
            if(preg_match('/^(.*?)(<=|>=|<|>|=)(.*?)$/',$and,$m)){
                $a=trim($m[1]);$b=trim($m[3]);
                if(empty($a)) $a=$current;
                else if(is_numeric($a)) $a=0+$a;
                else if(isset($data[$a])) $a=$data[$a];
                else {
                    $res=false; break;
                }
                if(empty($b)) $b=$current;
                else if(is_numeric($b)) $b=0+$b;
                else if(isset($data[$b])) $b=$data[$b];
                else {
                    $res=false; break;
                }
                if($m[2]=='<=') $res=$a<=$b;
                else if($m[2]=='>=') $res=$a>=$b;
                else if($m[2]=='>') $res=$a>$b;
                else if($m[2]=='<') $res=$a<$b;
                else if($m[2]=='=') $res=$a==$b;
            } else {
                $res=false;
                //throw new \Exception('Некорректное условие в строке '.$and)
            }
            if(!$res) break; // выход по AND
        }
        if($res) break; // выход по OR
    }
    return $res;
}

$data=['count'=>3];

var_dump(true===evaluate(45,'count=2,<2;count=3,<300,>44', $data));
var_dump(true===evaluate(1,'<2'));
var_dump(true===evaluate(1,'>3;<2,>1;<2'));
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы