Me encargaron actualizar algunas condiciones en una aplicación. Tengo un conjunto de datos para evaluar, y ha sido codificado en la aplicación de la siguiente manera:
$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;
y así...
Es una pesadilla para mantener en muchos lugares.
Lo que esencialmente estoy buscando es hacer alguna forma de pasar la cadena de consulta para evaluar los datos. Para comenzar, una fórmula simple podría definirse como una matriz
$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]);
}
}
Esto podría extenderse y llamarse recursivamente
$formula = [['a','=','apple'], 'AND', ['e','<','10']]
pero lo que estoy buscando esencialmente es almacenar fórmulas a una cadena, como:
"((([a]="orange") OR ([c]<"4")) AND ([g]="red"))"
donde [] identificaría las claves de la matriz
o tal vez algo como en Excel
"AND(OR(IF('a'='orange'),IF('c'<4)),IF('g'='red'))"
¿Hay alguna solución limpia para hacer esto? Tengo una idea de cómo construir una biblioteca completa para ello, tal vez en el futuro.
No quiero agregar nuevas condiciones al código cada vez. Ya están en toda la aplicación. Sería mejor almacenarlo en la configuración y extenderlo o modificarlo en un solo lugar.
Cualquier ayuda muy apreciada.
eval()
.Respuestas:
Así que esta es solo una solución rápida, pero funciona para mí en este momento.
Si hay [a] en la fórmula, se tratará como clave de matriz.
En esta solución funcionará con fórmulas como:
No es exactamente lo que quería, pero hace el trabajo, y no es tan terrible (espero). Necesita un poco de verificación de entrada y manejo de errores, pero esto es solo un ejemplo.
fuente