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;
}