CodeIgniter:帮助解决此查询

问题描述 投票:0回答:2

我刚刚开始我的第一个 CI 应用程序。我有一个显示一些帖子的视图。每个帖子可以有多个评论,我想在每个帖子旁边显示评论总数。

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

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;
        }
    }
}
php codeigniter
2个回答
3
投票

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

我通常将它们构建在模型中的多级数组中,就像这样......

注意:此模型返回一个帖子或所有帖子,并包含可通过

->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

请注意,一旦您构建了像我在模型中所示的 posts 数组,对于每个 $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 传递给该方法来指定单个帖子。 这样,可以重复使用相同的模型方法来详细显示单个帖子,并显示所有评论。


0
投票

在您的控制器中:

  • 我认为在“城市”模型中包含“博客”内容很奇怪,因此您可能会考虑重命名。
  • 我总是更喜欢使用 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()
    方法正在执行此功能
  • 此方法将无条件返回零个或多个对象的数组。
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();
    }
}

在您看来:

  • 如果您不喜欢在视图中进行大量的
    <?php
    ?>
    标签的跳进跳出,并且认为短标签是有争议的,那么下一个代码片段将使用带有传入变量的模板字符串。
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 } ?>
© www.soinside.com 2019 - 2024. All rights reserved.