使用 CodeIgniter 显示表行以及另一个表的每行计数

发布于 2024-10-10 19:08:04 字数 2683 浏览 2 评论 0原文

我有一个显示一些帖子的视图。每个帖子可以有多个评论,我想在每个帖子旁边显示评论总数。

到目前为止,我所有的数据库调用都在我的控制器中(我将更改它)。

function index() {
    $data['query'] = $this->db->get('posts');
    $this->load->view('blog_view', $data);
}

在我看来:

<?php foreach($query->result() as $row): 
      <div class="post-box">
          <p><?php echo $row->body; ?><small>&nbsp;added by <?php echo $row->username; ?> on  <?php echo date ('d/m/Y',strtotime($row->created)); ?>&nbsp;<a href="<?php echo base_url(); ?>blog/comments/<?php echo $row->id; ?>"><img src="<?php echo base_url(); ?>images/comments_icon.png" />&nbsp;0</a></small></p>
      </div>
<?php endforeach; ?>

我想获取评论总数,其中 comment.post_id = 当前记录的 id。并将其显示在评论图标旁边。

更新

控制器:

function index(){
    //load the model
    $this->load->model('City_model');

    //call the model method
    $data->posts = $this->City_model->get_posts();
    
    
    $this->load->view('blog_view', $data);
}

模型(city_model.php):

<?php

class City_model extends Model{

    function get_posts($id = NULL) {
        
        //define optional id for single post
        //if an id was supplied
        if ( $id != NULL ) {
            $this->db->where('id',$id);
        }

        // execute query
        $query = $this->db->get('posts');

        //make sure results exist
        if($query->num_rows() > 0) {
            $posts = $query->result();
        } else {
            return FALSE;
        }

        //create array for appended (with comments) posts
        $appended_posts_array = array();

        //loop through each post
        foreach ($posts as $post) {

            //get comments associated with the post
            $this->db->where('post_id', $post->id)
            $comments = $this->db->get('comments');

            //if there are comments, add the comments to the post object
            if($comments->num_rows() > 0) {
                $post->comments = $comments;
            }
            else {
                $post->comments = array();
            }

            //rebuild the returned posts with their comments
            $appended_posts_array[] = $post;

        }

        //if post id supplied, only return the single post object
        if ($id != NULL) {
            return $appended_registration_array[0];
        }
        else {
            return $appended_registration_array;
        }
    }
}

I have a view that displays some posts. Each post can have multiple comments and I want to display the total number of comments next to each post.

So far all my database calls are in my controller (I'll be changing this).

function index() {
    $data['query'] = $this->db->get('posts');
    $this->load->view('blog_view', $data);
}

In my view:

<?php foreach($query->result() as $row): 
      <div class="post-box">
          <p><?php echo $row->body; ?><small> added by <?php echo $row->username; ?> on  <?php echo date ('d/m/Y',strtotime($row->created)); ?> <a href="<?php echo base_url(); ?>blog/comments/<?php echo $row->id; ?>"><img src="<?php echo base_url(); ?>images/comments_icon.png" /> 0</a></small></p>
      </div>
<?php endforeach; ?>

I want to get the total number of comments where comment.post_id = the current record's id. and display it next to the comments icon.

UPDATE

Controller:

function index(){
    //load the model
    $this->load->model('City_model');

    //call the model method
    $data->posts = $this->City_model->get_posts();
    
    
    $this->load->view('blog_view', $data);
}

Model (city_model.php):

<?php

class City_model extends Model{

    function get_posts($id = NULL) {
        
        //define optional id for single post
        //if an id was supplied
        if ( $id != NULL ) {
            $this->db->where('id',$id);
        }

        // execute query
        $query = $this->db->get('posts');

        //make sure results exist
        if($query->num_rows() > 0) {
            $posts = $query->result();
        } else {
            return FALSE;
        }

        //create array for appended (with comments) posts
        $appended_posts_array = array();

        //loop through each post
        foreach ($posts as $post) {

            //get comments associated with the post
            $this->db->where('post_id', $post->id)
            $comments = $this->db->get('comments');

            //if there are comments, add the comments to the post object
            if($comments->num_rows() > 0) {
                $post->comments = $comments;
            }
            else {
                $post->comments = array();
            }

            //rebuild the returned posts with their comments
            $appended_posts_array[] = $post;

        }

        //if post id supplied, only return the single post object
        if ($id != NULL) {
            return $appended_registration_array[0];
        }
        else {
            return $appended_registration_array;
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦醒时光 2024-10-17 19:08:04

这是一个示例模型方法,采用我通常对具有“子”项目的项目执行的方法...

我通常将它们构建在模型中的多级数组中,如下所示...

注意:此模型返回一篇文章或所有文章,包含可通过 ->comments 属性访问的一组相关评论。

function get_posts($id = NULL) {

    //define optional id for single post
    //if an id was supplied
    if ( $id != NULL ) {
        $this->db->where('id',$id);
    }

    // execute query
    $query = $this->db->get('posts');

    //make sure results exist
    if($query->num_rows() > 0) {
        $posts = $query->result();
    } else {
        return FALSE;
    }

    //create array for appended (with comments) posts
    $appended_posts_array = array();

    //loop through each post
    foreach ($posts as $post) {

        //get comments associated with the post
        $this->db->where('post_id', $post->id)
        $comments = $this->db->get('comments');

        //if there are comments, add the comments to the post object
        if($comments->num_rows() > 0) {
            $post->comments = $comments;
        }
        else {
            $post->comments = array();
        }

        //rebuild the returned posts with their comments
        $appended_posts_array[] = $post;

    }

    //if post id supplied, only return the single post object
    if ($id != NULL) {
        return $appended_registration_array[0];
    }
    else {
        return $appended_registration_array;
    }       
}

现在在控制器中...

function posts() {

    //load the model
    $this->load->model('model_name');

    //call the model method
    $data->posts = $this->model_name->get_posts();

    //load the view
    $this->load->view('view/file', $data);

}

然后在视图中您可以使用嵌套的 foreach循环浏览帖子和评论

<? foreach($posts as $post): ?>                //posts foreach start

    <h1><?= $post->title ?></h1>  //post title
    <p><?= $post->body ?></p>     //post body

    <? foreach($post->comments as $comment): ?>     //comments foreach start       
        <h3><?= $comment->author ?></h3>  //comment author
        <p><?= $comment->body ?></h3>     //comment body
    <? endforeach; ?>                               // end comments foreach

<? endforeach; ?>        // end posts foreach

请注意,一旦您构建了像我在模型中所示的帖子数组,对于每个 $post 项目,您都会有一个 $post->comments,它只是与关联的评论数组那个帖子,因此知道这一点后,您可以在控制器或视图中调用 count($post->comments) 来获取与单个帖子相关的评论数。

因此,对于您关于仅显示计数的问题,在视图中唯一的变化是您不会循环遍历所有评论,您只需这样做...

<? foreach($posts as $post): ?>                //posts foreach start

    <h1><?= $post->title ?></h1>             //post title
    <p><?= count($post->comments) ?></p>     //comment count


<? endforeach; ?>        // end posts foreach

编辑:
我向模型方法添加了可选参数 $id ,这样如果您愿意,您可以通过将其 id 传递给该方法来指定单个帖子。这样,可以重复使用相同的模型方法来详细显示单个帖子,并显示所有评论。

Here is an example model method that takes the approach I usually do for Items that have "sub" items...

I generally build them in a Multi-level array in the model like so...

Note: this model returns a post or all posts, complete with an array of associated comments accessable through the ->comments property.

function get_posts($id = NULL) {

    //define optional id for single post
    //if an id was supplied
    if ( $id != NULL ) {
        $this->db->where('id',$id);
    }

    // execute query
    $query = $this->db->get('posts');

    //make sure results exist
    if($query->num_rows() > 0) {
        $posts = $query->result();
    } else {
        return FALSE;
    }

    //create array for appended (with comments) posts
    $appended_posts_array = array();

    //loop through each post
    foreach ($posts as $post) {

        //get comments associated with the post
        $this->db->where('post_id', $post->id)
        $comments = $this->db->get('comments');

        //if there are comments, add the comments to the post object
        if($comments->num_rows() > 0) {
            $post->comments = $comments;
        }
        else {
            $post->comments = array();
        }

        //rebuild the returned posts with their comments
        $appended_posts_array[] = $post;

    }

    //if post id supplied, only return the single post object
    if ($id != NULL) {
        return $appended_registration_array[0];
    }
    else {
        return $appended_registration_array;
    }       
}

Now in the controller...

function posts() {

    //load the model
    $this->load->model('model_name');

    //call the model method
    $data->posts = $this->model_name->get_posts();

    //load the view
    $this->load->view('view/file', $data);

}

Then in the view you can use a nested foreach to loop through the posts AND the comments

<? foreach($posts as $post): ?>                //posts foreach start

    <h1><?= $post->title ?></h1>  //post title
    <p><?= $post->body ?></p>     //post body

    <? foreach($post->comments as $comment): ?>     //comments foreach start       
        <h3><?= $comment->author ?></h3>  //comment author
        <p><?= $comment->body ?></h3>     //comment body
    <? endforeach; ?>                               // end comments foreach

<? endforeach; ?>        // end posts foreach

Take note that once you build the posts array like I have shown in the model, for each $post item you have a $post->comments that is simply an array of comments that are associated with that post, so knowing that, you can call count($post->comments) in the controller or view to get the number of comments related to a single post.

So for your question about just displaying the count, in the view the only change is that you wouldn't loop through all the comments, you'd just do this instead...

<? foreach($posts as $post): ?>                //posts foreach start

    <h1><?= $post->title ?></h1>             //post title
    <p><?= count($post->comments) ?></p>     //comment count


<? endforeach; ?>        // end posts foreach

EDIT :
I added the optional parameter $id to the model method so that if you want you can specify a single post if you wish, by passing it's id to the method. That way this same model method can be re-used to display single posts in detail with all comments displayed also.

旧瑾黎汐 2024-10-17 19:08:04

在你的控制器中:

  • 我认为在“城市”模型中包含“博客”内容很奇怪,所以你可能会考虑重命名。
  • 我总是更喜欢使用 StudlyCase 对加载的模型进行别名 - 它更好地符合 PSR 标准。我觉得 Snake_case 只会让脚本看起来很旧并且稍微更冗长。
  • 对于“读取”请求,$id 应通过 $_GET 传入,并且可以作为控制器方法的单独参数进行最简单的访问。
  • 我总是输入提示并努力缩小可能的类型(传入和传出)。
public function index(?int $id = null): void
{
    $this->load->model('Blog_model', 'BlogModel');

    $this->load->view('blog_view', [
        'posts' => $this->BlogModel->getPostsWithCommentCount($id),
    ]);
}

在模型中:

  • 除了极少数例外,变量应该作为方法参数传递到模型方法中;尽量保持参数数量最少。
  • 仅当 $id 不为空或零时才添加 WHERE 子句。
  • 您不需要执行迭代查询,因此您不应该这样做。
  • 使用 LEFT JOIN 关联评论表,并使用 COUNT() 进行 GROUP BY 以将评论总数附加到每个博客行。
  • 您可能希望 ->order_by('created', 'DESC') 或其他列以保持一致的表示。如果是这样,请在 ->group_by() 之后和 ->get() 之前链接新方法。
  • 没有 ->from() 方法调用,因为 ->get() 方法正在添加 FROM 子句并执行查询。
  • 此方法将无条件返回零个或多个对象的数组。
class Blog_model extends CI_Model
{
    public function getPostsWithCommentCount(?int $id = null): array
    {
        if ($id) {
            $this->db->where('posts.id', $id);
        }
        return $this->db
            ->select('posts.*, COUNT(comments.id) total_comments')
            ->join('comments', 'comments.post_id = posts.id', 'LEFT');
            ->group_by('posts.id')
            ->get('posts')
            ->result();
    }
}

在您的视图中:

  • 如果您不喜欢在视图中大量跳入和跳出 ?> 标记,并且认为短标记存在争议,下一个代码片段将使用带有传入变量的模板字符串。
foreach ($posts as $post) {
    printf(
        '<div class="post-box">
             <p>%s <small>added by %s on %s <a href="%s"><img src="%s"> %s</a></small></p>
         </div>
        ',
        $post->body,
        $post->username,
        date('d/m/Y', strtotime($post->created)),
        base_url("blog/comments/$post->id"),
        base_url('images/comments_icon.png'),
        $post->total_comments
    );
}
  • 或者,如果您更喜欢大量开始和结束 PHP 标记,请使用以下代码片段。
<?php foreach ($posts as $post) { ?>
    <div class="post-box">
        <p>
            <?php echo $post->body; ?> 
            <small>
                added by <?php echo $post->username; ?> on <?php echo date('d/m/Y', strtotime($post->created)); ?>
                <a href="<?php echo base_url("blog/comments/$post->id"); ?>">
                    <img src="<?php echo base_url('images/comments_icon.png'); ?>"> 
                    <?php echo $post->total_comments; ?>
                </a>
            </small>
        </p>
    </div>
<?php } ?>

In your Controller:

  • I think it is odd to have "blog" content in a "city" model, so you might consider renaming.
  • I always prefer to alias loaded models using StudlyCase -- it just better aligns with PSR standards. I feel snake_case just makes scripts look old and slightly more verbose.
  • For a "reading" request, the $id should be passed in via $_GET and can be most simply accessed as a lone parameter of the controller method.
  • I always type hint and endeavor to keep possible types narrow (incoming and outgoing).
public function index(?int $id = null): void
{
    $this->load->model('Blog_model', 'BlogModel');

    $this->load->view('blog_view', [
        'posts' => $this->BlogModel->getPostsWithCommentCount($id),
    ]);
}

In your Model:

  • With very few exceptions, variables should be passed into model methods as method parameters; try to keep the number of parameters minimal.
  • Only add a WHERE clause if the $id is not null or zero.
  • You don't need to perform iterated queries and therefore YOU SHOULDN'T.
  • Use a LEFT JOIN to relate the comments table and GROUP BY with COUNT() to append the total number of comments to each blog row.
  • You may wish to ->order_by('created', 'DESC') or another column for consistent presentation. If so, chain the new method after ->group_by() and before ->get().
  • There isn't a ->from() method call because the ->get() method is adding the FROM clause and executing the query.
  • This method will unconditionally return an array of zero or more objects.
class Blog_model extends CI_Model
{
    public function getPostsWithCommentCount(?int $id = null): array
    {
        if ($id) {
            $this->db->where('posts.id', $id);
        }
        return $this->db
            ->select('posts.*, COUNT(comments.id) total_comments')
            ->join('comments', 'comments.post_id = posts.id', 'LEFT');
            ->group_by('posts.id')
            ->get('posts')
            ->result();
    }
}

In your View:

  • If you don't like doing a lot of jumping in and out of <?php and ?> tags in views and think short tags are controversial, the next snippet will use a template string with passed in variables.
foreach ($posts as $post) {
    printf(
        '<div class="post-box">
             <p>%s <small>added by %s on %s <a href="%s"><img src="%s"> %s</a></small></p>
         </div>
        ',
        $post->body,
        $post->username,
        date('d/m/Y', strtotime($post->created)),
        base_url("blog/comments/$post->id"),
        base_url('images/comments_icon.png'),
        $post->total_comments
    );
}
  • Or if you prefer lots of opening and closing PHP tags, then use the following snippet.
<?php foreach ($posts as $post) { ?>
    <div class="post-box">
        <p>
            <?php echo $post->body; ?> 
            <small>
                added by <?php echo $post->username; ?> on <?php echo date('d/m/Y', strtotime($post->created)); ?>
                <a href="<?php echo base_url("blog/comments/$post->id"); ?>">
                    <img src="<?php echo base_url('images/comments_icon.png'); ?>"> 
                    <?php echo $post->total_comments; ?>
                </a>
            </small>
        </p>
    </div>
<?php } ?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文