foreach循环中的codeigniter查询,该查询将返回一个sigle数组


codeigniter query within foreach loop which will return a sigle array

我正在尝试访问类别下的所有子类别,但对我不起作用

function getAllSubCategory($CatId)
    {
        $data=array();
        $this->db->select('c.catId,c.cat_name,c.cat_alias,c.cat_image,c.parentcatid,c.isHeading');
        $this->db->from('coupon_category as c');
        $this->db->where('c.parentcatid', $CatId);
        $query = $this->db->get();
        if($query->num_rows()>0)
        {
            $data = $dataFetched = $query->result_array();
            $query->free_result();  
            foreach ($dataFetched as $row) {
                $this->db->select('c.catId,c.cat_name,c.cat_alias,c.cat_image,c.parentcatid,c.isHeading');
                $this->db->from('coupon_category as c');
                $this->db->where('c.parentcatid', $dataFetched->catId);
                $data = $query->result_array();
                $query->free_result();  
            }
        }
        echo count($data);
        return $data;
    }

但不工作,不知道我错在哪里。

问题在这里

  $this->db->where('c.parentcatid', $dataFetched->catId);

应该是

 $this->db->where('c.parentcatid', $row ["catId"]);

代码存在以下问题:

  • 内部循环将新的结果集分配给变量$data,从而丢失$data中以前的值
  • 在该循环的每次迭代中,您将再次重复完全相同的查询。你没有在循环中使用$row变量
  • 数据结构似乎不支持更深层次的嵌套子类别允许

如果要获取子类别及其子类别。。。等等,你应该使用递归,即使表中只有两个级别的子类别仍然是好的代码。

以下是一些代码,用于使其朝着您要去的方向工作,使用递归,并使用函数array_merge在执行时附加数据。

function getAllSubCategory($CatId)
{
    $this->db->select('c.catId,c.cat_name,c.cat_alias,c.cat_image,c.parentcatid,c.isHeading');
    $this->db->from('coupon_category as c');
    $this->db->where('c.parentcatid', $CatId);
    $query = $this->db->get();
    $dataFetched = $query->result_array();
    $query->free_result();
    $data = array();
    foreach ($dataFetched as $row) {
        $data[] = $row;
        $data = array_merge($data, getAllSubCategory($row["catId"]));
    }
    echo count($data);
    return $data;
}

备选方案

你可以通过做对数据库的分层查询(例如要求此处),但我不知道它是否可以与Active Record一起使用。所以我会提供根据我自己给出的答案,使用普通query()语法的代码对于这个特殊的问题:

function getAllSubCategory($CatId)
{
    $CatId = $this->db->escape($CatId); // sanitise to prevent SQL injection
    $query = $this->db->query(
        "select c.catId,c.cat_name,c.cat_alias,c.cat_image,c.parentcatid,c.isHeading
         from   (select * from coupon_category
                 order by parentcatid, catId) as c,
                (select @pv := '$CatId') as initialisation
         where  find_in_set(c.parentcatid, @pv) > 0
         and    @pv := concat(@pv, ',', catId)");
    $data = $query->result_array();
    $query->free_result();
    echo count($data);
    return $data;
}

请注意,最后一个解决方案要求对于每个记录parentcatid<catid,否则结果将不完整。

但如果是这样的话,这肯定会在性能上胜过第一个解决方案,因为它只执行一个数据库查询。

此外,如果表有循环,其中节点的子节点也是其父节点(例如),则第一个解决方案将保持循环和查询,直到出现内存不足错误。最后一个解决方案不会,因为它只查找parentcatid<catid