目的
複雑な比較をPHP配列として保存しようとしています。次に、配列を読み取って変数のグループを評価し、ステートメントがtrueかfalseかを返します。
質問
複雑な比較を保存して、後で読み取ってその時点で存在する変数を評価できるようにするにはどうすればよいですか?これはこれを達成するための最良の方法ですか?あなたの助けは大歓迎です。
例、英語
If($ source = 200 OR $ source = 300)AND($ age <10 OR $ age> 60)THAN return true Else return false
注: 変数はコード内の任意の変数にすることができます。ここでは例としてsourceとageを使用しました。ネストされた配列は、例よりも深くすることもフラットにすることもできます。
例、コード
$conditions = Array
(
[relation] => AND
[0] => Array
(
[relation] => OR
[0] => Array
(
[var] => source
[compare] => =
[value] => 300
)
[1] => Array
(
[var] => source
[compare] => =
[value] => 300
)
)
[1] => Array
(
[relation] => OR
[0] => Array
(
[var] => age
[compare] => <
[value] => 10
)
[1] => Array
(
[var] => age
[compare] => >
[value] => 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";
}