在PHP中将多维数组转换为条件表达式

时间:2019-06-30 13:38:17

标签: php arrays

我正在尝试将数组转换为类似条件的表达式字符串,该字符串将在JS Filtrex库中使用。 JS部分与这个问题无关。

以下是我尝试使用的示例PHP数组。

$condition = array(
    'and',
    array(
        array(
            'field' => 'show_image',
            'compare' => '==',
            'value' => 1
        ),
    ),
    array(
        'or',
        array(
            'field' => 'filter',
            'compare' => '!=',
            'value' => 1
        ),
        array(
            'field' => 'align',
            'compare' => '==',
            'value' => 'left'
        )
    )
);

结果字符串将如下所示:

show_image == 1 and ( filter != 1 or align == "left" )

我没有出售数组结构,因此只要可以在更多条件下进行扩展,您就可以自由修改数组。

谢谢。

3 个答案:

答案 0 :(得分:0)

我不知道它是否在所有情况下都有效,但在您的情况下,效果很好(我想)

我建议您删除嵌套数组$condition[1]并直接写入$condition[1][0]数组(新的数组结构在下面的代码中)

<?php

$condition = array(
    'and',
    array(
            'field' => 'show_image',
            'compare' => '==',
            'value' => 1
    ),
    array(
        'or',
        array(
            'field' => 'filter',
            'compare' => '!=',
            'value' => 1
        ),
        array(
            'field' => 'align',
            'compare' => '==',
            'value' => 'left'
        )
    )
);

function generateExpression( Array $condition ) : String
{
 return $condition['field'] . " " . $condition['compare'] . " " . $condition['value'];
}

function generateConditionExpression ( Array $conditionTree ) : String
{
  if ( array_key_exists("field",$conditionTree)  ) 
  {
     return generateExpression($conditionTree);
  }
  //else
  return "(" . generateConditionExpression( $conditionTree[1] ) . " " . $conditionTree[0] . " " . generateConditionExpression( $conditionTree[2] ) . ")";

}

echo generateConditionExpression($condition);

答案 1 :(得分:0)

您只需要递归这样的结构,并根据第一个元素进行切换:

  • 如果是字符串,则将其余参数视为操作数/表达式,joined由运算符

  • 对于关联数组,只需将字段/比较/值连接成字符串

例如:

function join_expr($opts) {
    if (isset($opts["compare"])) {    // optional ↓↓↓ caretaking of value type(!)
        return "($opts[field] $opts[compare] '$opts[value]')";
    }
    elseif (gettype($opts[0]) == "string") {
        $op = array_shift($opts);
        return join(
            " $op ",
            array_map("join_expr", $opts)   // recurse on operands/subexpressions
        );
    }
    elseif (count($opts) == 1) {   // somewhat redundant
        return "(" . join_expr($opts[0]) . ")";
    }
    else {
        trigger_error("wrong struct");
    }
}

答案 2 :(得分:0)

使用嵌套foreach()的一种方法,

<?php
$condition = array(
    'AND',
    array(
        array(
            'field' => 'grid_enable',
            'compare' => '==',
            'value' => 1
        ),
    ),
    array(
        array(
            'field' => 'grid_column',
            'compare' => '>=',
            'value' => 3
        ),
    ),
    array(
        'OR',
        array(
            'field' => 'filter',
            'compare' => '!=',
            'value' => 1
        ),
        array(
            'field' => 'align',
            'compare' => '==',
            'value' => 'left'
        )
    ),
    array(
        array(
            'field' => 'grid_gutter',
            'compare' => '==',
            'value' => 'large'
        ),
    ),
);
$final_result = '';
$double = false;
foreach($condition as $k=>$v){
    $result = [];
    if(!is_array($v)){
        $operator_out = $v;
    }else{
        foreach($v as $k1=>$v1){
            if(!is_array($v1)){
                $operator_inn = $v1;
            }else{
                $result[] = implode(' ',array_values($v1));
            }
        }
    }
    if(count($result) == 1){
        if($double){
            $final_result.= " ".$operator_out." ".$result[0];    
        }else{
            $final_result.= $result[0]." ".$operator_out." ";    
        }
    }
    else if(count($result) == 2){
        $final_result.= "(".implode(" $operator_inn " , $result).")";
        $double= true;
    }
}
echo $final_result;
?>

演示: https://3v4l.org/BWmus