评估存储在数组中的PHP逻辑 客观的
我试图将复杂的比较存储为PHP数组。然后我想读取数组来计算一组变量,并返回该语句是真还是假 问题: 如何存储复杂的比较,以便以后可以读取和计算当时存在的变量?这是实现这一目标的最佳方式吗?非常感谢你的帮助 例如,英语 如果($source=200或$source=300)和($age<10或$age>60),则返回true 否则返回false 注意事项: 变量可以是代码中的任何变量,我在这里使用了source和age作为示例。嵌套数组可以比示例更深或更平坦 例如,代码评估存储在数组中的PHP逻辑 客观的,php,arrays,operator-keyword,Php,Arrays,Operator Keyword,我试图将复杂的比较存储为PHP数组。然后我想读取数组来计算一组变量,并返回该语句是真还是假 问题: 如何存储复杂的比较,以便以后可以读取和计算当时存在的变量?这是实现这一目标的最佳方式吗?非常感谢你的帮助 例如,英语 如果($source=200或$source=300)和($age60),则返回true 否则返回false 注意事项: 变量可以是代码中的任何变量,我在这里使用了source和age作为示例。嵌套数组可以比示例更深或更平坦 例如,代码 $conditions=Array ( [关
$conditions=Array
(
[关系]=>和
[0]=>阵列
(
[关系]=>或
[0]=>阵列
(
[var]=>来源
[比较]=>=
[值]=>300
)
[1] =>阵列
(
[var]=>来源
[比较]=>=
[值]=>300
)
)
[1] =>阵列
(
[关系]=>或
[0]=>阵列
(
[var]=>年龄
[比较]=><
[值]=>10
)
[1] =>阵列
(
[var]=>年龄
[比较]=>>
[值]=>60
)
)
)
解决方案
根据@sam grondahl的回答
函数可以处理您可以抛出的任何嵌套逻辑。
接受正则表达式和数值比较
$source = '300';
$age = '60';
$input_variables = array('source' => $source, 'age' => $age);
$conditions = array(
'relation' => 'and',
array(
'relation' => 'and',
array(
'var' => 'source',
'compare' => 'regex',
'value' => '(200|300)+'
),
array(
'relation' => 'OR',
array(
'var' => 'age',
'compare' => '=',
'value' => '59'
),
array(
'var' => 'age',
'compare' => '=',
'value' => '60'
)
)
),
array(
'relation' => 'or',
array(
'var' => 'age',
'compare' => '<',
'value' => '10'
),
array(
'var' => 'age',
'compare' => '>=',
'value' => '60'
)
),
array(
'var' => 'source',
'compare' => '=',
'value' => '300'
),
);
function evaluateConditions($condArray, $varablesArray){
if(!$condArray || !is_array($condArray)){throw new Exception('Missing Conditions Input Array');}
if(!$varablesArray || !is_array($varablesArray)){throw new Exception('Missing Variables Input Array');}
//PULL VARIABLES FROM ARRAY
foreach($varablesArray as $key_var => $value_var){
${$key_var} = $value_var;
}
///PROCESS THE ARRAY THAT CONTAINS THE COMPARISON ARRAY
if (!$condArray['relation']){
//FORMAT COMPARE INPUT
$condArray['compare'] = strtoupper(trim($condArray['compare']));
$condArray['compare'] = preg_replace('/^=$/','==',$condArray['compare']);
///ACCEPTED COMPARE VALUES
$accepted_compare_array = array('=','==','===','<>','!=','!==','>','>=','<','<=','REGEX');
//VERIFY REQUIRED FIELDS ARE PRESENT
if(!$condArray['var']){throw new Exception('Missing var');}
if(!$condArray['compare']){throw new Exception('Missing compare');}
if(!$condArray['value']){throw new Exception('Missing value');}
//VERIFY ALL VALUES
if($condArray['compare'] != 'REGEX' && !is_numeric($condArray['value'])){throw new Exception('Value is Not Numeric');}
if(!in_array($condArray['compare'], $accepted_compare_array)){throw new Exception('Invalid Compare Value');}
if(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/",$condArray['var'])){throw new Exception('Invalid Var');}
if($condArray['compare'] == 'REGEX'){
$condArray['compare'] = preg_replace('/\//','\/',$condArray['compare']);
$eval_str = 'if(preg_match("/'.$condArray['value'].'/i", $'.$condArray['var'].')){return 1;} else{return 0;}';
}
else{
$eval_str = 'if($'.$condArray['var'].' '.$condArray['compare'].' '.$condArray['value'].'){return 1;} else{return 0;}';
}
return eval($eval_str);
}
else{
$condArray['relation'] = strtoupper(trim($condArray['relation']));
//VERIFY RELATION VALUE
$accepted_relation_array = array('AND','OR');
if(!in_array($condArray['relation'], $accepted_relation_array)){throw new Exception('Relation Invalid');}
//VERIFY THAT AT LEAST TWO ARRAYS
$array_count = 0;
foreach($condArray as $condArray_var){
if(is_array($condArray_var)){$array_count++;}
}
if($array_count < 2){throw new Exception('Missing Comparison Array');}
}
if (strtoupper($condArray['relation']) == 'OR') {
unset($condArray['relation']);
$eval_str = 'if(';
for($i=0; $i < count($condArray); $i++){
$eval_str .= evaluateConditions($condArray[$i], $varablesArray);
if($i != count($condArray)-1){$eval_str .= ' || ';}
}
$eval_str .= '){return 1;}else{return 0;}';
return eval($eval_str);
}
if (strtoupper($condArray['relation']) == 'AND'){
unset($condArray['relation']);
$eval_str = 'if(';
for($i=0; $i < count($condArray); $i++){
$eval_str .= evaluateConditions($condArray[$i], $varablesArray);
if($i != count($condArray)-1){$eval_str .= ' && ';}
}
$eval_str .= '){return 1;}else{return 0;}';
return eval($eval_str);
}
throw new Exception('General Error Occurred');
} //end of function
/////
try {
echo evaluateConditions($conditions, $input_variables);
}
catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
$source='300';
$age='60';
$input_variables=array('source'=>$source,'age'=>$age);
$conditions=数组(
'关系'=>'和',
排列(
'关系'=>'和',
排列(
'var'=>'source',
'比较'=>'正则表达式',
'值'=>'(200 | 300)+'
),
排列(
'关系'=>'或',
排列(
'var'=>'age',
“比较”=>“=”,
“值”=>“59”
),
排列(
'var'=>'age',
“比较”=>“=”,
“值”=>“60”
)
)
),
排列(
'关系'=>'或',
排列(
'var'=>'age',
“比较”=>“=”,
“值”=>“60”
)
),
排列(
'var'=>'source',
“比较”=>“=”,
“值”=>“300”
),
);
函数evaluateConditions($condArray,$varablesArray){
if(!$condArray | |!is_array($condArray)){抛出新异常('Missing Conditions Input array');}
如果(!$varablesArray | |!is_数组($varablesArray)){抛出新异常('Missing Variables Input array');}
//从数组中提取变量
foreach($varablesArray作为$key\u var=>$value\u var){
${$key\u var}=$value\u var;
}
///处理包含比较数组的数组
if(!$condArray['relation']){
//格式比较输入
$condArray['compare']=strtoupper(trim($condArray['compare']);
$condArray['compare']=preg_replace(“/^=$/”、“==”、$condArray['compare']);
///接受的比较值
$accepted\u compare\u array=array(“=”、“=”、“=”、“!=”、“!=”、“!=”、“>”、“>=”、“处理此问题的最简单方法是使用PHP的eval()方法进行递归(http://php.net/manual/en/function.eval.php):
这是为处理字符串而设计的,但可以很容易地修改。此外,您可能应该检查以确保每个子数组的结构都正确,但我忽略了这段代码。感谢您的响应。我不知道它是否能工作,因为eval()中的$inArray[0]可能是另一组嵌套数组。可能我只需要将结构限制在一个级别。抱歉,忘记了包含递归:0。但是它现在在那里,所以这应该适用于任何程度的嵌套(只要函数堆栈没有溢出)。看起来$INARAY变量中有一个输入错误(额外的“r”)。有几个语法问题使解决方案无法在PHP中100%运行。但是您的逻辑非常正确!我在上面发布了我的完整解决方案。全局变量是邪恶的。不要使用它们!也许您可以重新考虑您的逻辑,因为可能有其他方法来处理您的问题。解决方案不再使用全局变量。感谢德维兹。
$source = '300';
$age = '60';
$input_variables = array('source' => $source, 'age' => $age);
$conditions = array(
'relation' => 'and',
array(
'relation' => 'and',
array(
'var' => 'source',
'compare' => 'regex',
'value' => '(200|300)+'
),
array(
'relation' => 'OR',
array(
'var' => 'age',
'compare' => '=',
'value' => '59'
),
array(
'var' => 'age',
'compare' => '=',
'value' => '60'
)
)
),
array(
'relation' => 'or',
array(
'var' => 'age',
'compare' => '<',
'value' => '10'
),
array(
'var' => 'age',
'compare' => '>=',
'value' => '60'
)
),
array(
'var' => 'source',
'compare' => '=',
'value' => '300'
),
);
function evaluateConditions($condArray, $varablesArray){
if(!$condArray || !is_array($condArray)){throw new Exception('Missing Conditions Input Array');}
if(!$varablesArray || !is_array($varablesArray)){throw new Exception('Missing Variables Input Array');}
//PULL VARIABLES FROM ARRAY
foreach($varablesArray as $key_var => $value_var){
${$key_var} = $value_var;
}
///PROCESS THE ARRAY THAT CONTAINS THE COMPARISON ARRAY
if (!$condArray['relation']){
//FORMAT COMPARE INPUT
$condArray['compare'] = strtoupper(trim($condArray['compare']));
$condArray['compare'] = preg_replace('/^=$/','==',$condArray['compare']);
///ACCEPTED COMPARE VALUES
$accepted_compare_array = array('=','==','===','<>','!=','!==','>','>=','<','<=','REGEX');
//VERIFY REQUIRED FIELDS ARE PRESENT
if(!$condArray['var']){throw new Exception('Missing var');}
if(!$condArray['compare']){throw new Exception('Missing compare');}
if(!$condArray['value']){throw new Exception('Missing value');}
//VERIFY ALL VALUES
if($condArray['compare'] != 'REGEX' && !is_numeric($condArray['value'])){throw new Exception('Value is Not Numeric');}
if(!in_array($condArray['compare'], $accepted_compare_array)){throw new Exception('Invalid Compare Value');}
if(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/",$condArray['var'])){throw new Exception('Invalid Var');}
if($condArray['compare'] == 'REGEX'){
$condArray['compare'] = preg_replace('/\//','\/',$condArray['compare']);
$eval_str = 'if(preg_match("/'.$condArray['value'].'/i", $'.$condArray['var'].')){return 1;} else{return 0;}';
}
else{
$eval_str = 'if($'.$condArray['var'].' '.$condArray['compare'].' '.$condArray['value'].'){return 1;} else{return 0;}';
}
return eval($eval_str);
}
else{
$condArray['relation'] = strtoupper(trim($condArray['relation']));
//VERIFY RELATION VALUE
$accepted_relation_array = array('AND','OR');
if(!in_array($condArray['relation'], $accepted_relation_array)){throw new Exception('Relation Invalid');}
//VERIFY THAT AT LEAST TWO ARRAYS
$array_count = 0;
foreach($condArray as $condArray_var){
if(is_array($condArray_var)){$array_count++;}
}
if($array_count < 2){throw new Exception('Missing Comparison Array');}
}
if (strtoupper($condArray['relation']) == 'OR') {
unset($condArray['relation']);
$eval_str = 'if(';
for($i=0; $i < count($condArray); $i++){
$eval_str .= evaluateConditions($condArray[$i], $varablesArray);
if($i != count($condArray)-1){$eval_str .= ' || ';}
}
$eval_str .= '){return 1;}else{return 0;}';
return eval($eval_str);
}
if (strtoupper($condArray['relation']) == 'AND'){
unset($condArray['relation']);
$eval_str = 'if(';
for($i=0; $i < count($condArray); $i++){
$eval_str .= evaluateConditions($condArray[$i], $varablesArray);
if($i != count($condArray)-1){$eval_str .= ' && ';}
}
$eval_str .= '){return 1;}else{return 0;}';
return eval($eval_str);
}
throw new Exception('General Error Occurred');
} //end of function
/////
try {
echo evaluateConditions($conditions, $input_variables);
}
catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
static function evaluateArray($inArray)
{
if (!$inArray['relation']) return eval($inArray['var'] + $inArray['compare'] + $inArray['value']);
if ($inArray['relation'] == 'OR') return eval(evaluateArray($inArray[0])+'||'+evaluateArray($inArray[1]));
if ($inArray['relation'] == 'AND') return eval(evaluateArray($inArray[0])+'&&'+evaluateArray($inArray[1]));
return false; //could throw exception here if you wanted
}