关于php:Codeigniter在视图中调用另一个控制器

Codeigniter call other controller in view

如何在一个视图中合并两个控制器。

我有两个控制器:

1。 PostController

2。 CommentController

帖子控制器将显示数据库中的所有帖子,并且这些帖子可以有评论。对于注释,我使用另一个控制器CommentController以避免DRY。在html循环中的帖子列表中,我尝试附加注释,如果所有存在于其ID上的帖子均存在。

在我的PostController> indexAction()中获取所有帖子

1
2
3
4
5
6
7
8
9
10
11
12
13
// controllers/PostController.php
/**
 * List all posts
 *
 */

public function index()
{
    $data = array(
        'posts' => $this->post->findAll(),
    );

    $this->load->view('post/index', $data);
}

这是comment controller中的方法,用于列出分配post_id

的注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// controllers/CommentController.php

/**
 * List all comments assigning post id
 *
 * @param int $post_id
 */

public function index($post_id)
{
    $data = array(
        'comments' => $this->comment->findAllByPostId($post_id), // <-- SELECT * FROM comments WHERE post_id = {post_id}
    );

    $this->load->view('comment/index', $data);
}

现在在post/index中获取所有帖子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php if($posts): ?>
<?php foreach ($posts as $post): ?>
     <?= $post->title; ?>
     <?= $post->text; ?>

     
       <!-- How to call here comment controller and index($post->post_id) -->
       <!-- i can use load->view('comment/index') but with this i do nothin i need to assigning  post id

       <!-- Need somthing $commentObject->index($post->post_id) but this in MVC is not good idea -->
   

<?php endforeach() ;?>
<?php endif; ?>

还有其他解决方案吗?

解决这个问题的我的方法是将所有控制器都放在一个Post中。但是我认为这是不好的做法,因为我以后会干。我需要其他ex的注释控制器(PictureController也可以具有我不想干的注释)

也许我的流程或组织不好?

ps。我为此进行搜索,但结果对我没有帮助


控制器从模型获取数据。因此,一般而言,模型中将发生任何数据库交互,然后控制器会询问"您是否获得了我的信息?如果是,请显示它,如果不是,则执行其他操作"。看法。

一个控制器可以从许多不同的模型调用,并且可以向视图发送多于一个的数据结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    public function index()
    {
            // assuming you have a model called 'post'
            // check if any posts came back from the search
            if( ! $posts  = $this->post->findAll() )
            {
                $this->_showNoPostsReturned() ;
            }

            // now assuming you have a model called comment
            // in your model you will have to foreach through posts etc

           // did any comments come back?
           elseif( ! $comments = $this->comment->returnFor($posts) )
           {
               $this->_showOnlyThe($posts) ;
           }
           // else we have posts and comments
           else{ $this->_showBoth($posts,$comments) ; }

  }

  private function _showBoth($posts,$comments){

   // this is how you pass more then one data structure
   // array, object, text, etc etc
   // with $data['name']

   $data['posts'] =  $posts ;
   $data['comments'] =  $comments ;

   // and call more then one view if necessary
   $this->load->view('post/index', $data);
   $this->load->view('comment/index', $data);

   }

因此,此索引方法仅从模型中请求数据,然后取决于它是否返回任何数据-它调用一个单独的私有方法,并且该方法可以调用适当的视图。换句话说,现在您无需在视图中执行此操作

1
<?php if($posts): ?>

这就是您要避免的内容,因为视图正在决定要显示的内容。显然,视图中将发生一些逻辑,但是所有决策都应尽可能在控制器中发生。


首先,我认为您确实想进行DRY,因为DRY的意思是"不要重复自己"。我认为您已经掌握了这个概念,但是读到您"不想干燥"有点令人困惑;)

答案

第二:在一种经典的MVC方法(CodeIgniter确实做到了)中,确实确实让控制器处理了模型,然后将模型(或来自模型的数据)传递给视图。

对于如何从控制器中检索所需的所有数据,现在有不同的概念,例如与仅传递"发布"模型并让视图在视图本身中删除发布评论相比,实际上是在控制器中读取所有内容,然后将其传递给视图。我认为两者都有正当的理由,即使我更喜欢后者,您也可以决定使用哪一个。

一种替代方法是使用"装饰器模式"(请参阅??Wikipedia),该模式似乎仅在CodeIgniter中具有用户层实现:https://github.com/ccschmitz/codeigniter-decorator

TL; DR

您的方法很好,但是您可以研究装饰器模式(请参见上文)。