вложенный код foreach - PullRequest
2 голосов
/ 28 июля 2011

В 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 ]

2 голосов
/ 28 июля 2011

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 голос
/ 28 июля 2011

пара баллов

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; ?>
1 голос
/ 28 июля 2011

В коде есть несколько ошибок, которые могут быть причиной этого.

  1. У вас есть дополнительная закрывающая скобка до конца цикла foreach в вашем контроллере.
  2. По вашему мнению, вы просматриваете категорию книг как $ book , но затем пытаетесь работать с объектом $ row внутри цикла. Попробуйте изменить это на $ book .
  3. Также, по вашему мнению, вы пытаетесь вывести некоторый HTML, не закрывая свои теги PHP. Теги <li> в вашем коде находятся внутри вашего блока PHP, а затем вы снова пытаетесь открыть новый блок PHP, даже не закрывая первый.
0 голосов
/ 11 сентября 2015

Я сталкивался с этим и пытался следовать примеру, опубликованному @mattumotu, и это было действительно полезно, но я думаю, что в нем могут быть некоторые ошибки - особенно в отношении способа индексации массива, а затем его повторения.Если вы используете число в качестве значения идентификатора, и ваши идентификаторы не начинаются с нуля и увеличиваются в числовом порядке от 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 категории, чтобы гарантировать, что мы перемещаемся по всем нашим элементам в числовом порядке по их идентификатору категории, по существу перечисляя элементы по категориям.

Контроллер:

$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), который будет отслеживать каждый раз, когда мы нажимаем новый идентификатор категории, и переменную для идентификатора категории, чтобы проверить, изменился ли наш идентификатор категории ($ curCatID).Если мы получим новый идентификатор категории, мы знаем, что мы собрали все элементы для этой категории, поэтому мы увеличиваем счетчик curCatIndex:

$curCatIndex+=1;

Поскольку наш $ curCatID начинается какNULL, когда мы начинаем наш цикл, мы увеличиваем $ curCatIndex, чтобы наш массив начинался с индекса 0.

Каждый раз, когда мы нажимаем новый идентификатор категории, мы помещаем имя этой категории в наш массив $ Categories:

$categories[$curCatIndex] = $category_name;

и установите $ curCatID равным нашему новому идентификатору:

$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, чтобы убедиться, что мы выбрали правильное измерение из нашего массива элементов.

Тогда внутри этого цикла вы можете делать все, что захотите.Здесь я просто распечатываю уникальный идентификатор моего предмета:

echo $image_item['id'];

Возможно, это более элегантный способ сделать это, но надеюсь, что он кому-нибудь поможет.Я на некоторое время ударился головой об стену.Спасибо mattumotu за то, что вы вывели меня на правильный путь.Я разместил более понятный пример кода здесь:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...