Php 将平面树数组转换为MYSQL where子句,同级表示OR,子代表示and

Php 将平面树数组转换为MYSQL where子句,同级表示OR,子代表示and,php,mysql,arrays,algorithm,Php,Mysql,Arrays,Algorithm,我有一个包含树数据的平面数组。树可以是任意长度,也可以是用户所需的深度。每个节点都有以下数据: id: 1, parent: 0, id: 2, parent: 1, equation: 'user.id = 1' id: 3, parent: 2, equation: 'user.id <> 2' id: 4, parent: 1, equation: 'user.id = 4' 这将导致一个OR语句 WHERE user.id = 3 OR user.id

我有一个包含树数据的平面数组。树可以是任意长度,也可以是用户所需的深度。每个节点都有以下数据:

id: 1,
parent: 0,

id: 2,
parent: 1,
equation: 'user.id = 1'

id: 3,
parent: 2,
equation: 'user.id <> 2'        

id: 4,
parent: 1,
equation: 'user.id = 4'
这将导致一个OR语句

WHERE user.id = 3 OR user.id = 4
树/数据源可以有任意数量的节点,包含任意数量的方程,我需要使用此数据结构构建一个查询字符串来表示和/或组合


我有点不知道从哪里开始使用算法。

这样做很有趣

$test=[ ['id'=> 1,'parent'=> 0],
        ['id'=> 2, 'parent'=> 1, 'equation'=> 'users.id = 1'],
        ['id'=> 3, 'parent'=> 2, 'equation'=> 'users.id <> 2'],        
        ['id'=> 4, 'parent'=> 1, 'equation'=> 'users.id = 4']
        ];
$in_where=[];       

echo  whereFromArray($test,$in_where);

function whereFromArray($array=[],&$in_where)
{
    $return='';

    foreach ($array as $key => $value) {

        $result=search($array, 'parent', $value['id']);

        if (count($result)) {//has children

            $return.= 'OR ('. str_replace('OR ', 'AND ', whereFromArray($result,$in_where)) .') ';

        }elseif(!in_array($value['id'], $in_where)){

            $return.= 'OR '.$value['equation'].' ';
            $in_where[]=$value['id'];
        }
    }

    return ltrim(ltrim($return,'AND '),'OR ');

}

function search($array, $key, $value)
{
    $results = array();

    if (is_array($array)) {


        foreach ($array as $subarray) {

            if (isset($subarray[$key]) && $subarray[$key] === $value) {

                $results[] = $subarray;

            }

        }

    }

    return $results;
}
$test=[['id'=>1,'parent'=>0],
['id'=>2,'parent'=>1,'等式'=>'users.id=1'],
['id'=>3,'parent'=>2,'equation'=>users.id 2'],
['id'=>4,'parent'=>1,'等式'=>'users.id=4']
];
$in_,其中=[];
echo whereFromArray($test,$in_where);
函数whereFromArray($array=[],&$in_where)
{
$return='';
foreach($key=>$value的数组){
$result=search($array,'parent',$value['id']);
如果(count($result)){//有子项
$return.='OR('.str_replace('OR','AND',whereFromArray($result,$in_where)));
}elseif(!in_数组($value['id'],$in_where)){
$return.='或'$value['公式'].';
$in_,其中[]=$value['id'];
}
}
返回ltrim(ltrim($return,'AND'),'OR');
}
函数搜索($array,$key,$value)
{
$results=array();
if(is_数组($array)){
foreach($array作为$subarray){
if(isset($subarray[$key])&&&$subarray[$key]==$value){
$results[]=$subarray;
}
}
}
返回$results;
}

因此,此函数将在正确的位置构建一个包含所有子句元素的数组,我只需要对数组进行内爆。也可以使用连接的字符串来完成

function where_builder( $elements = array(), &$clause = array(), $index = 0)
{
    //
    $element_children = $this->return_array_where( $elements, 'parent', $elements[$index]['id'] );

    //
    $x=0;
    foreach( $element_children as $key => $value ) 
    {
        if( $x > 0 )
            array_push( $clause, ' OR ' );

        if( count( $element_children ) > 1  )
            array_push( $clause, ' ( ' );

        //
        $element_grandchildren = $this->return_array_where( $elements, 'parent', $value['id'] );

        //  
        array_push( $clause, $value['equation'] );
        //
        if( count( $element_grandchildren ) > 0 )
        {   
            array_push( $clause, ' AND ' );

            $pointer = $this->get_first_key_where( $elements, 'id', $value['id'] );

            $this->where_builder( $elements, $clause, $pointer );
        }

        if( count( $element_children ) > 1 )
            array_push( $clause, ' ) ' );

        $x++;
    }
    return $clause;
}

当你说用户需要的深度。这里的深度是什么样的?示例数组只演示了一个维度。总的来说,只要提供尽可能多的信息;更多细节。你可以想象很难完全理解你需要什么。谢谢罗伯特,我添加了更多的细节,希望能让你更好地理解我的意思。谢谢,但它似乎使每个化合物都成为OR,而不是和/或,这取决于它与周围方程的关系。我在上面添加了更多的细节,这可能会使问题变得更清楚。嗯,你只需要对我的回答做一些修改就可以了是的,你肯定为我指明了正确的方向。我可以以此为基础。非常感谢。
id: 1,
parent: 0,

id: 2,
parent: 1,
equation: 'users.id = 3'

id: 3,
parent: 1,
equation: 'users.id = 4'      
WHERE user.id = 3 OR user.id = 4
$test=[ ['id'=> 1,'parent'=> 0],
        ['id'=> 2, 'parent'=> 1, 'equation'=> 'users.id = 1'],
        ['id'=> 3, 'parent'=> 2, 'equation'=> 'users.id <> 2'],        
        ['id'=> 4, 'parent'=> 1, 'equation'=> 'users.id = 4']
        ];
$in_where=[];       

echo  whereFromArray($test,$in_where);

function whereFromArray($array=[],&$in_where)
{
    $return='';

    foreach ($array as $key => $value) {

        $result=search($array, 'parent', $value['id']);

        if (count($result)) {//has children

            $return.= 'OR ('. str_replace('OR ', 'AND ', whereFromArray($result,$in_where)) .') ';

        }elseif(!in_array($value['id'], $in_where)){

            $return.= 'OR '.$value['equation'].' ';
            $in_where[]=$value['id'];
        }
    }

    return ltrim(ltrim($return,'AND '),'OR ');

}

function search($array, $key, $value)
{
    $results = array();

    if (is_array($array)) {


        foreach ($array as $subarray) {

            if (isset($subarray[$key]) && $subarray[$key] === $value) {

                $results[] = $subarray;

            }

        }

    }

    return $results;
}
function where_builder( $elements = array(), &$clause = array(), $index = 0)
{
    //
    $element_children = $this->return_array_where( $elements, 'parent', $elements[$index]['id'] );

    //
    $x=0;
    foreach( $element_children as $key => $value ) 
    {
        if( $x > 0 )
            array_push( $clause, ' OR ' );

        if( count( $element_children ) > 1  )
            array_push( $clause, ' ( ' );

        //
        $element_grandchildren = $this->return_array_where( $elements, 'parent', $value['id'] );

        //  
        array_push( $clause, $value['equation'] );
        //
        if( count( $element_grandchildren ) > 0 )
        {   
            array_push( $clause, ' AND ' );

            $pointer = $this->get_first_key_where( $elements, 'id', $value['id'] );

            $this->where_builder( $elements, $clause, $pointer );
        }

        if( count( $element_children ) > 1 )
            array_push( $clause, ' ) ' );

        $x++;
    }
    return $clause;
}