嵌套的foreach codeigniter

时间:2011-07-28 10:24:13

标签: php codeigniter foreach

在codeigniter 1.73我试图按类别显示书籍。所以,如果我有一个名为汽车的类别,我应该看到汽车内的书籍清单。所以我尝试了一个嵌套的foreach循环来完成这个但似乎无法让它工作。

<?php

class Book_model extends Model {


    function books_by_category()
    {
        $this->db->select('*');
        $this->db->from('categories');
        $this->db->join('books', 'books.category_id = categories.id');

        $query = $this->db->get();
        return $query->result();        
    }
}

然后在视图中:

foreach($data as $category) {

  if (sizeof($category['books']))
  {
    foreach($category['books'] as $book)
    {
      <li>$book->book_number anchor("book/chapters/$book->id", $book->book_title)</li>  
    }
  } else {
    // show 'no books'
  }
}

控制器:

function index() {

    $data = array();

    if($query = $this->book_model->books_by_category())
    {
        $data['books_by_category'] = $query;

        foreach($query as $row)
        {
            if (!isset($data[$row['id']]))
            {
                $data[$row['id']] = $row;
                $data[$row['id']]['books'] = array();
            }  


            $data[$row['id']]['books'][] = $row;


        }                   

        $data['main_content'] = 'books_view';
        $this->load->view('includes/template', $data);      
    }
}

4 个答案:

答案 0 :(得分:2)

Foreach没有像您使用过的“else”子句。

foreach($category['books'] as $book)
{
  // show books

} else {
// show 'no books'
}

相反,你可以这样做:(我的PHP生锈了)

if(count($category['books']) <= 0)
{
    //No books
}
else
{
    foreach($category['books'] as $book)
    {
        //You have books
    }
}

答案 1 :(得分:1)

代码中有一些错误可能导致此错误。

  1. 在控制器的foreach循环结束之前,您有一个额外的结束括号。
  2. 在您看来,您正在浏览图书类别作为$ book ,但之后您正在尝试使用循环内的 $ row 对象。尝试将其更改为 $ book
  3. 同样在您的视图中,您尝试输出一些HTML而不关闭PHP标记。代码中的<li>标记位于PHP块中,然后您尝试再次打开一个新的PHP块而不关闭第一个。

答案 2 :(得分:1)

几点

function books_by_category()
{
    $this->db->select('*');
    $this->db->from('categories');
    $this->db->join('books', 'books.category_id = categories.id');

    $query = $this->db->get();
    return $query->result();        
}

此代码返回具有类别集的类别和书籍的所有列,这真的是您要做的吗?函数名称'books_by_category'会告诉我你只对一个特定类别的书感兴趣,从查看你的问题我猜这不是这种情况。

假设您正在尝试获取所有书籍但按类别对其进行分组,我会执行以下操作:

模型

function get_books()
{
    $this->db->select('*');
    $this->db->from('books');
    $this->db->join('categories', 'categories.id = books.category_id');
    $query = $this->db->get();

    if($query->num_rows() == 0)
    {
        #no books
        return false;
    }
    return $query->result();
}

控制器

function index() {
    $data = array();

    $book_list = $this->book_model->get_books();
    if($book_list)
    {
        $categories = array();
        $books_by_category = array();

        foreach($book_list as $book)
        {
            $category_id = $book['category.id'];
            $category_name = $book['category.name'];

            if(array_key_exists($category_id, $categories))
            {
                $categories[$category_id] = $category_name;
            }

            if(array_key_exists($category_id, $books_by_category))
            {
                $books_by_category[$category_id] = array();
            }

            $books_by_category[$category_id][] = $book;
        }

        $data['categories'] = $categories;
        $data['books_by_category'] = $books_by_category;
    }

    $data['main_content'] = 'books_view';
    $this->load->view('includes/template', $data);      
}

和视图

<?php if(isSet($books_by_category)) : ?>

<?php foreach($books_by_category as $category => $book_list): ?>

<p>Category: <?php echo $categories[$category]; ?></p>

<ul>
<?php foreach($book_list as $book) : ?>

<li><?php echo $book->book_number; ?>. <?php echo anchor('bible/chapters/' . $book->id, $book->book_title); ?></li>

<?php endforeach; ?>
</ul>

<?php endforeach; ?>

<?php else: ?>

<p>Sorry dude, no books.</p>

<?php endif; ?>

答案 3 :(得分:0)

我遇到了这个,并试图跟随发布的示例@mattumotu,它确实有用,但我认为它可能有一些错误 - 特别是对数组的索引方式然后循环。如果您使用数字作为id值,并且您的id不是从零开始并且以0到x的数字顺序增加,那么当您尝试循环遍历数组时,您将在视图中获得未知的索引顺序(至少我做了)。所以我修改了如下示例(注意我稍微更改了变量名称以供我自己使用):

型号:

public function get_imagery_by_category(){

    $this->db->select('extra_imagery.*', FALSE); //MH - not sure what FALSE does here
    $this->db->select('extra_image_categories.id as cat_id, extra_image_categories.name as cat_name', FALSE); //MH alias the category id and name as they are the same column names as the imagery name and id
    $this->db->from('extra_imagery');
    $this->db->join('extra_image_categories', 'extra_image_categories.id = extra_imagery.cat'); //get all images where the image cat matches category id
    $this->db->order_by('extra_image_categories.id');
    $query = $this->db->get();

    if($query->num_rows() == 0){
        return false;
    } else {
        return $query->result_array();
    }

}

我们只是按类别ID对所有项目进行排序,以确保我们按类别ID按数字顺序浏览所有项目,基本上按类别列出项目。

控制器:

$imagery_list = $this->imagery_model->get_imagery_by_category();

if($imagery_list){
    $categories = array();
    $imagery_by_category = array();
    $curCatIndex = -1;
    $curCatID = NULL;
    foreach($imagery_list as $i=>$image){

        $category_id = $image['cat_id'];
        $category_name = $image['cat_name'];
        if ($curCatID != $category_id){
            $curCatIndex+=1;
            $categories[$curCatIndex] = $category_name;
            $curCatID = $category_id;
        }
        $imagery_by_category[$curCatIndex][] = $image;

    }

    //print_r($imagery_by_category);

    $data['categories'] = $categories;
    $data['imagery_by_category'] = $imagery_by_category;
}

在这里,我们设置一个数组来保存我们的类别和一个数组来保存我们的项目。 $ imagery_by_category将是一个多维数组,这样第一个类别中的所有项目都会在第一个数组中结束,第二个类别中的所有项目都在第二个数组中,等等。像这样:

$imagery_by_category[0][0] = category0, item0 $imagery_by_category[0][1] = category0, item1 $imagery_by_category[1][0] = category1, item0

我们设置一个计数器($ curCatIndex),它将跟踪我们每次点击新的类别ID,以及类别ID的变量,以检查我们的类别ID是否已更改($ curCatID)。如果我们点击了新的类别ID,我们知道我们已经收集了该类别的所有项目,因此我们增加了curCatIndex计数器:

$curCatIndex+=1;

因为我们的$ curCatID在我们开始循环时以NULL开始,所以我们递增$ curCatIndex,以便我们的数组将从索引0开始。

每当我们点击新的类别ID时,我们会将该类别的名称推送到$ categories数组:

$categories[$curCatIndex] = $category_name;

并将$ curCatID设置为我们的新id:

$curCatID = $category_id;

然后,无论我们是否属于新类别,我们都会将项目推送到多维数组中的适当位置:

$imagery_by_category[$curCatIndex][] = $image;

最后我们只是将这些数组提供给我们的视图:

$data['categories'] = $categories; $data['imagery_by_category'] = $imagery_by_category;

然后,在我们看来:

<?php if(isSet($imagery_by_category)) : ?>
    <?php foreach($categories as $i=>$category_item): ?>
        <p><?php echo $category_item ?></p>
        <?php foreach($imagery_by_category[$i] as $image_item) : ?>
            <?php
            echo $image_item['id'];
            ?>
        <?php endforeach; ?>
    <?php endforeach; ?>
<?php else: ?>
<p>No imagery</p>
<?php endif; ?>

我们有一个嵌套循环。外循环遍历我们的类别:

<?php foreach($categories as $i=>$category_item): ?>

请注意,我们已添加变量$ i来跟踪循环索引(即数组索引)

然后我们打印出该类别的名称:

<p><?php echo $category_item ?></p>

然后内循环遍历该类别中的项目:

<?php foreach($imagery_by_category[$i] as $image_item) : ?>

注意我们在这里使用$ i变量以确保我们从item数组中选择正确的维度。

然后在这个循环中你可以做任何你想做的事情。在这里,我只是打印出我项目的唯一ID:

echo $image_item['id'];

可能是一种更优雅的方式来做到这一点,但希望它可以帮助某人。我把头撞在墙上一段时间了。感谢mattumotu让我走上正轨。我在这里发布了一个更清晰的代码示例:

http://mikeheavers.com/main/code-item/order_items_in_one_database_table_by_categories_from_another_database_table