Мне было поручено обновить некоторые условия в приложении. У меня есть набор данных для оценки, и он был жестко запрограммирован в приложении следующим образом:
$arr = array(
'a' => 'apple',
'b' => 'orange',
'c' => 1,
'd' => 2,
'e' => 5,
'f' => 'green',
'g' => 'red',
'h' => 'yellow',
)
$res1 = ($arr['a'] == 'apple') ? TRUE : FALSE;
$res2 = (($arr['b'] == $arr['f']) && ($arr['c'] < $arr['d']) ? TRUE : FALSE;
$res3 = (($arr['e'] == '5') && $res2) ?TRUE : FALSE;
и так далее...
Это кошмар, чтобы поддерживать во многих местах.
По сути, я ищу способ передать строку запроса для оценки данных. Для начала простую формулу можно определить как массив
$formula = ['a', '=', 'apple'];
function query($formula, $arr) {
switch ($formula[1]) {
case '=':
return ($arr[$formula[0]] == $formula[2]);
case '!=':
return ($arr[$formula[0]]!= $formula[2]);
case '>':
return ($arr[$formula[0]] > $formula[2]);
case '<':
return ($arr[$formula[0]] == $formula[2]);
}
}
Затем это можно расширить и вызвать рекурсивно
$formula = [['a','=','apple'], 'AND', ['e','<','10']]
но то, что я по сути ищу, это хранить формулы в виде строки, например:
"((([a]="orange") OR ([c]<"4")) AND ([g]="red"))"
где [] идентифицирует ключи массива
или может быть что-то вроде в Excel
"AND(OR(IF('a'='orange'),IF('c'<4)),IF('g'='red'))"
Есть ли чистое решение для этого? У меня есть идея, как создать целую библиотеку для этого, возможно, в будущем.
Я не хочу добавлять новые условия в код каждый раз. Они уже во всем приложении. Было бы лучше хранить его в конфигурации и расширять или модифицировать в одном месте.
Любая помощь высоко ценится.
eval()
.Ответы:
Так что это только быстрое решение, но у меня работает прямо сейчас.
Если в формуле есть [a], он будет рассматриваться как ключ массива.
В этом решении это будет работать с формулой как:
Это не совсем то, что я хотел, но делает работу, и не так страшно (я надеюсь). Требуется некоторая проверка ввода и обработка ошибок, но это всего лишь пример.
источник