【问题标题】:CodeIgniter 4 Populating menu from database on View LayoutCodeIgniter 4 在视图布局上从数据库填充菜单
【发布时间】:2025-11-28 07:30:01
【问题描述】:

总的来说,我是 CodeIgniter 的新手。我有一个视图布局,其中有导航菜单栏。我想用我保存在数据库中的类别填充下拉菜单。

这是我的布局的 sn-p (View\layouts\frontend.php):

<nav class="navbar navbar-expand-md sticky-top">
    <div class="collapse navbar-collapse flex-column " id="navbar">
        <!-- Brand bar -->
        <a class="navbar-brand ml-3" href="#">
            <span class="">Test Site</span>
        </a>
        <!-- Internal links Menu navbar -->
        <ul class="navbar-nav justify-content-center w-100 px-3">
            <li class="nav-item">
                <a class="nav-link" href="#">Home</a>
            </li>
            <li class="nav-item dropdown">
                <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    Categories
                </a>
                <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
                    <a class="dropdown-item" href="#">News</a>
                    <a class="dropdown-item" href="#">Event</a>
                    <a class="dropdown-item" href="#">Announcement</a>
                </div>
            </li>
        </ul>
</nav>

现在,我了解在扩展该布局的每个视图上,我可以在控制器上进行查询并返回带有数据的视图。这是我到目前为止所做的,它确实有效。

家庭控制器:

use App\Models\CategoryModel;

class Home extends BaseController
{
    public function index()
    {
        $categoryModel = new CategoryModel();
        $data['categories'] = $categoryModel->orderBy('id', 'ASC')->findAll();
        
        return view('frontend/home_page', $data);
    }
}

部分布局:

<li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        Categories
    </a>
    <?php if ($categories) : ?>
        <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
            <?php foreach ($categories as $category) : ?>
                <a class="dropdown-item" href="#"><?php echo $category['name'] ?></a>
            <?php endforeach; ?>
        </div>
    <?php endif; ?>
</li>

但看起来我必须在所有控制器的函数上执行此操作,这些函数呈现使用我的布局 (frontend.php) 的视图。 我想问的是,是否有可能只制作一个函数/类/某事来调用,所以它只完成一次?在这种情况下,最佳做法是什么?

【问题讨论】:

    标签: php model-view-controller codeigniter-4


    【解决方案1】:

    如果

    $categoryModel = new CategoryModel();
    $data['categories'] = $categoryModel->orderBy('id', 'ASC')->findAll();
    

    是您计划在该控制器中调用多个方法的东西,那么是的,将代码推到可重用的东西中将被认为是最佳实践。

    您表面上可以在几个不同的地方定义这个函数,但在这种情况下,私有控制器函数可能是最简单的(它必须是私有的以防止它被提供通过网络请求):

    private getCategories(){
      $categoryModel = new CategoryModel();
      $ret['categories'] = $categoryModel->orderBy('id', 'ASC')->findAll();
      return $ret;
    }
    

    同一控制器中的任何其他函数都可以通过调用获取该数据

    $this-&gt;getCategories().

    【讨论】:

    • 也许我不够清楚。我想要的是在我的所有视图调用的布局模板上填充类别列表。如果我应用您的方法(或我正在使用的方法),我必须在我的所有控制器上重新声明 getCategories(),如果我错了,请纠正我。有没有办法只声明一次 getCategories() 并且可以在所有控制器中使用?
    • @tuxguitar 您在 BaseController 中定义所有其他控制器 extend 中的函数。
    【解决方案2】:

    如果有人遇到同样的问题,这就是我的处理方式。 Codeigniter 有一个很好的功能view_cell()。您可以在 Libraries 文件夹中创建一个单独的类(让我们用方法 Menu 将其称为 display()),然后返回一个带有菜单的单独视图。然后在你的布局中调用&lt;?= view_cell('\App\Libraries\Menu::display') ?&gt;。这样就不需要在多个控制器中重复相同的代码了。

    【讨论】: