I'd like to creat a library list by category

I’m working through KY’s book and decided to play with creating a library to be displayed by category and I’d like the category to only show once at the beginning of the list of related books. Since I’m new this is all pretty basic.
Here’s the controller code I have so far with the 'foreach statment below that. If Javascript I would create a different function to run the code multiple times on the same page but that doesn’t feel correct in PHP. Can you point me in the right direction?

$result = mysqli_query($link,
		'SELECT title, author, publisher, pubdate, category.name
		FROM books INNER JOIN category
		ON books.categoryId = category.id
		ORDER BY pubdate ASC');
		
if (!$result)
{
	$error = 'Error fetching books: ' . mysqli_error($link);
	include 'error.html.php';
	exit();
}

while ($row = mysqli_fetch_array($result))
{
	$books[] = array('title' => $row['title'], 'author' => $row['author'], 'publisher' => $row['publisher'], 'date' => $row['pubdate'], 'category' => $row['name']);
}


include 'books.html.php';
<ul>
     <?php foreach ($books as $book): ?>
     <li><b><?php echo htmlspecialchars($book['title'], ENT_QUOTES, 'UTF-8'); ?></b><br />by:<em><?php echo htmlspecialchars($book['author'], ENT_QUOTES, 'UTF-8'); ?></em><br />
    	<span class="map">Publisher: <?php echo htmlspecialchars($book['publisher'], ENT_QUOTES, 'UTF-8'); ?> - <?php echo htmlspecialchars($book['date'], ENT_QUOTES, 'UTF-8'); ?></span><br /><?php echo htmlspecialchars($book['category'], ENT_QUOTES, 'UTF-8'); ?><br /></li>
    <?php endforeach; ?>
	</ul>

After you’ve fetched all the books, you’ll need to essentially index them by category.

$booksByCategory = array();
foreach ($books as $book) {
    // add this book to an array that is keyed by the book's category name
    $booksByCategory[$book['name']][] = $book;
}

Then in your template:

<?php foreach ($booksByCategory as $categoryName => $books): ?>
    <h2><?php echo htmlspecialchars($categoryName) ?></h2>
    <ul>
        <?php foreach ($books as $book): ?>
            <li>
                ...
            </li>
        <?php endforeach ?>
    </ul>
<?php endforeach ?>

Thanks Jeff. That makes sense to me but I’m struggling with it… more on this later.

Also, are there really that many braces here?

$booksByCategory[$book[‘name’]] = $book;

Thanks Frances

I know, right!? :stuck_out_tongue:

The inner-most set gets the category name…

$book[‘name’]

The outer set uses that name as a key in another array…

$booksByCategory[ $book[‘name’] ]

And that last pair means array push…

$booksByCategory[$book[‘name’]][]

Okay so what I’ve got now is a library list with numerical? headings and all books listed under each heading instead of being sorted by category… What have I done wrong?

$result = mysqli_query($link,
		'SELECT title, author, publisher, pubdate, category.name
		FROM books INNER JOIN category
		ON books.categoryId = category.id');
		
if (!$result)
{
	$error = 'Error fetching books: ' . mysqli_error($link);
	include 'error.html.php';
	exit();
}


while ($row = mysqli_fetch_array($result))
	{

	$books[] = array('title' => $row['title'], 'author' => $row['author'], 'publisher' => $row['publisher'], 'date' => $row['pubdate'], 'category' => $row['name']);
	$booksByCategory[] = array();

	foreach ($books as $book) {
    // add this book to an array that is keyed by the book's category name
    $booksByCategory[$books['category']][] = $book;
}
				
	}


 <?php foreach ($booksByCategory as $categoryName => $book): ?>

    <h2><?php echo htmlspecialchars($categoryName, ENT_QUOTES, 'UTF-8'); ?></h2>

     <?php foreach ($books as $book): ?>

       	<p><?php echo htmlspecialchars($book['title'], ENT_QUOTES, 'UTF-8'); ?> <span style="color:#3C6";><em>by: <?php echo htmlspecialchars($book['author'], ENT_QUOTES, 'UTF-8'); ?></em></span><br />
   		<?php echo htmlspecialchars($book['publisher'], ENT_QUOTES, 'UTF-8'); ?> - <?php echo htmlspecialchars($book['date'], ENT_QUOTES, 'UTF-8'); ?></p>

        <?php endforeach ?>

<?php endforeach ?>


There are a number of small typos.

$booksByCategory[] = array();
should be
$booksByCategory = array();

$booksByCategory[$books[‘category’]][] = $book;
should be
$booksByCategory[$book[‘category’]][] = $book;

and
<?php foreach ($booksByCategory as $categoryName => $book): ?>
should be
<?php foreach ($booksByCategory as $categoryName => $books): ?>

OMG! That completely rocks! Thank you so much for your time and efforts Jeff.