【问题标题】:Codeigniter - making my controllers more DRYCodeigniter - 让我的控制器更干燥
【发布时间】:2012-01-10 19:10:33
【问题描述】:

在我的 codeigniter 控制器函数中,我使用以下代码来生成我的视图并插入所有必要的内容:

        $left_column = $this->load->view('widgets/sub_navigation', $subnav_data, true);
        $left_column .= $this->load->view('widgets/search_box', '', true); //Set data to be loaded into columns
        $left_column_base = $this->load->view('widgets/assist_navigation', '', true);
        $center_column = 'this is center column';
        $right_column = $this->load->view('widgets/ask_us_a_question', '', true);
        $right_column .= $this->load->view('widgets/newsletter', '', true);
        $right_column .= $this->load->view('widgets/latest_news', '', true);

        $this->template->inject_partial('left_column', $left_column); //Inject data into the partial columns
        $this->template->inject_partial('left_column_base', $left_column_base);
        $this->template->inject_partial('center_column', $center_column);
        $this->template->inject_partial('right_column', $right_column);
        $this->template->build('template',$data); 

我使用的是三列布局,上面的代码规定了每列中显示的内容。它以非常模块化的方式工作,让我可以快速自定义每个页面。

有没有办法简化上面的代码,也许使用数组,以减少重复代码,让事情更干??

【问题讨论】:

  • 我以前从未听说过“DRY”这个词,有人能详细说明一下吗?
  • @DavidNguyen 你是认真的吗?在这种情况下,en.wikipedia.org/wiki/Don't_repeat_yourself
  • @DavidNguyen,这意味着不要重复自己,这是一种避免复制意大利面的模式。
  • @Esailija 重复代码不一定是“意大利面条代码”
  • 重复(然后稍作修改)的代码通常称为意大利面条代码。或Big Ball Of Mud antipattern

标签: php model-view-controller templates codeigniter dry


【解决方案1】:

您需要创建扩展 CI_Controller 的基本控制器。然后,您的所有控制器都会扩展您创建的某个基本控制器,具体取决于在调用该控制器的所有情况下需要做什么。

application/core 中创建一个名为MY_controller.php 的文件(前缀可以在config 中更改):

class MY_Controller extends CI_Controller {


    function __construct()
    {

        parent::__construct();


            /* Widgets are only prepared -- they will be fetched and rendered once layout->render is called.
               This saves the overhead of reading the files on requests where layout isn't rendered.
            */                  


        $this->layout->prepare_widget( "widgets/navigation", "navigation_widget" );
        $this->layout->prepare_widget( "widgets/footer", "footer_widget"  );
        $this->layout->prepare_widget( "widgets/twitter", "twitter_widget" );

    }


}


class Public_Controller extends MY_Controller {

    function __construct()
    {
        parent::__construct();
    }

}

class Admin_Controller extends MY_Controller {

    function __construct()
    {
        parent::__construct();

            if( !$this->user->has_permissions( PERMISSION_ADMIN ) )
            {
                redirect( base_url(), "location", 303 );    
                die();
            }
    }

}

class Member_Controller extends MY_Controller {

    function __construct()
    {
        parent::__construct();


            if( !$this->user->has_permissions( PERMISSION_REGISTERED ) )
            {
                redirect( base_url(), "location", 303 );
                die();
            }
    }

}

如您所见,所有子控制器都自动拥有小部件,因为它们扩展了公共、管理员或成员。扩展管理控制器的子控制器会自动检查权限,因此您无需再次执行此操作。您可以将此概念应用到您的应用中。

一个子控制器:(正常放置在application/controllers

class Articles extends Member_controller {

    ...

}

将自动确保用户已登录,并且无需执行任何操作即可准备好小部件,因为父类的父级已经准备好了它们。文章中需要做的就是调用$this->layout->render,如果逻辑最后需要布局渲染。

【讨论】:

    【解决方案2】:

    Codeigniter 控制器是根据事务脚本模式设计的,众所周知,当您的应用程序增长时,控制器往往会变大并且“不干燥”。

    为了防止这种情况,您可以重新实现视图以处理支持布局的两步复合视图模式。寻找一个布局视图 IIRC,codeigniter 网站上有一些。

    【讨论】:

      【解决方案3】:

      我写了一篇博文,解释了我的设计理念,即组织 CodeIgniter 控制器以使它们更加干燥。我喜欢让我的控制器的索引函数作为一个公共的入口/出口点,以避免重复所有控制器方法共有的操作。

      http://caseyflynn.com/2011/10/26/codeigniter-php-framework-how-to-organize-controllers-to-achieve-dry-principles/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多