Miałem za zadanie zaktualizować niektóre warunki w aplikacji. Mam zestaw danych do oceny i został on zakodowany na stałe w aplikacji w następujący sposób:
$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;
i tak dalej...
To koszmar w wielu miejscach.
Zasadniczo szukam sposobu, aby przekazać ciąg zapytania w celu oceny danych. Na początek prostą formułę można zdefiniować jako tablicę
$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]);
}
}
Można to następnie rozszerzyć i wywołać rekurencyjnie
$formula = [['a','=','apple'], 'AND', ['e','<','10']]
ale zasadniczo szukam formuł ciągów, takich jak:
"((([a]="orange") OR ([c]<"4")) AND ([g]="red"))"
gdzie [] identyfikuje klucze tablicy
a może coś w stylu Excela
"AND(OR(IF('a'='orange'),IF('c'<4)),IF('g'='red'))"
Czy jest na to jakieś czyste rozwiązanie? Mam pomysł, jak zbudować dla niego całą bibliotekę, może w przyszłości.
Nie chcę dodawać nowych warunków do kodu za każdym razem. Są już w całej aplikacji. Lepiej byłoby przechowywać go w konfiguracji i rozszerzać lub modyfikować w jednym miejscu.
Każda pomoc bardzo doceniana.
eval()
.Odpowiedzi:
Jest to więc tylko szybkie rozwiązanie, ale teraz działa dla mnie.
Jeśli formuła zawiera [a], będzie traktowana jak klucz tablicy.
W tym rozwiązaniu będzie działać z formułą taką jak:
Nie jest to dokładnie to, czego chciałem, ale spełnia swoją rolę i nie jest tak straszne (mam nadzieję). Wymaga sprawdzenia danych wejściowych i obsługi błędów, ale to tylko przykład.
źródło