0

CodeIgniter로 사이트를 만들고 있는데 Blog_model이라는 모델이 있습니다.OOP, MVC - 모델 및 객체

Blog_model에는 특정 주제에 대한 게시물 목록을 가져 오는 방법이 있습니다 (예 : getPopularPosts()).

getPopularPosts()은 지정된 테이블과 일치하는 topic_id의 게시물 목록에 대해 게시물 테이블을 쿼리하고 인기순으로 정렬합니다. 따라서 전체 게시물 테이블에 대한 쿼리는 topic_idx 인 모든 게시물을 찾기 위해 결국에는 매우 커질 것이라고 가정 해 봅시다.

그런 다음 foreach 결과가 asas 개 개인 게시 ID이면 새 Post 개체가 생성됩니다. Post 클래스는 id 필드를 설정하여 게시물을 구성합니다.

Post의 내용을 반환하려면 의 전체 행을 반환하기 위해 posts 테이블을 다시 쿼리하는 $post->getPost();을 할당합니다.

이 조직 (AFAIK)은 훌륭한 객체 지향 원칙을 따릅니다. 하지만 이제는 모든 게시물에 대해 (다시 말하자면, 수천, 수백만, 무엇이든간에 ...), 먼저 id의 목록을 쿼리 한 다음 각 게시물의 내용을 다시 얻어야합니다. 30 개의 게시물을 반환한다면 31 개의 별도 쿼리를 의미합니다.

달리, I는 객체 지향 패턴을 깨고 poststopic_id = X 각 게시물 * 당겨 있었다. 그런 다음 30 개의 게시물을 모두 반환하는 쿼리가 하나 있지만 객체 지향적이지 않습니다.

어떻게해야합니까?

+0

"개체 지향적 인 느낌"이 중요하다고 생각합니까? - 성능이나 무언가에 대해 걱정이된다면 백엔드에서 변경 사항을 완벽하게 수행하여 결과를 일반 텍스트 파일에 기록 할 수 있습니다. 그런 다음 각 게시물에 대해 쿼리를 실행하지 않아도됩니다. 초기 쿼리의 ID를 사용하여 캐시 된 파일의 결과를 표시 할 수 있습니다. 그러나 언급 한 옵션 중 하나를 선택하는 주석을 찾고 있다면 조인 된 쿼리로 갈 것입니다. 코드 점화 장치는 실수가 아니라면 엄격하게 oo가 아닙니다. Kohana 나는 생각합니다. 그리고 그들은 당신이 원하는 것을하기 위해 ORM을 가지고 있습니다. –

+0

차이가 있다면 CodeIgniter 2입니다. – Peter

+0

질문에 많은 정보가 있습니다. 여기에서 제대로 설명하기를 원한다면 코드에 대한 구체적인 예를 들어주십시오. – jondavidjohn

답변

3

많은 쿼리를 수행 할 이유가 없습니다. 기본적으로 특정 주제 ID에 해당하는 X 개의 게시물을 찾고 있습니다 ...이 객체를 하나의 객체로 반환 한 다음 PHP에서 결과를 반복해야합니다. 일단 도착하면 그렇게하는 것이 훨씬 빠르기 때문입니다 당신은 더 이런 식으로 가야한다

수백만 개의 행을 갖는 점 :

class blog_model extends CI_Model { 

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

    function getPopularPosts($cat_id){ 
     /* Using method chaining here since you sound like you 
      really want to utilize everything OO CI has to offer */ 
     $posts = $this->db->select('id, title, post_info') 
        ->where('topic_id', $topic_id) 
        ->get('posts'); 

     if($posts->num_rows() > 0){ 
      return $posts; 
     }else{ 
      return FALSE; 
     } 
    }  
} 

그런 다음 컨트롤러가 다음과 같을 것이다 :

class blog extends CI_Controller { 

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

    function blog_posts($popular_post_id) { 
     $this->load->model('blog_model'); 
     $posts = $this->blog_model->getPopularPosts($popular_post_id); 

     if(!empty($posts){ 
      foreach($posts as $post){ 
       echo $post->id; 
       echo $post->title; 
       echo $post->post_info; 
      } 
     }else{ 
      echo 'There are no posts'; 
     } 

    } 

} 

이 더 이익입니다 (그리고 실제로 큰 문제) f에서 쿼리 톤 생성 ashion 당신이 현재 그것을 설정, 대 쿼리에서 하나의 개체를 생성하고 컨트롤러의 각 행을 반복하고 데이터와 함께 필요한 뭐든지 할 수 있습니다.

+0

그러나 OOP의 정신 (그리고 아마도 이것은 숲을 잃어버린 나무를 의미한다)에서'Post' 클래스에 그러한 논리를 두는 것이 '정확하다'고 생각하지 않겠는가? 어쩌면 특정 게시물에 대한 답글을 얻고 싶을 수 있습니다. 자신의 메소드를 사용하면 getPost()와 getReplies()를 동일한 클래스에 넣을 수있다. 반대로,'getReplies()'는'Post' 클래스의 메소드가되어야합니다. – Peter

+1

그래, OOP이 실제로 의미하는 것의 의미와 구현 방법에 대한 배를 완전히 놓치고 있다고 생각합니다 ... 하나의 항목에 대한 응답을 얻으려면 blog_posts 모델과 쿼리 만 다른 함수 여야합니다 특정 블로그 게시물 ID ... 여러 게시물에 대해 여러 개의 답글을 얻으려면 몇 가지 MySQL JOIN을 수행 할 것입니다. 가장 간단한 방법은 가능한 한 적은 수의 쿼리를 사용하여 필요한 것을 성취하는 것입니다. OOP는 조직을 유지하기위한 일을 수행하는 방법 일뿐입니다. – tgriesser

+0

나는 처음에 당신이 묘사하는 방식대로 일을 시작했다고 언급 할 가치가있다. 귀하의 대답을 바탕으로, 나는이 설정으로 되돌아갔습니다. 코드의 전체적인 가중치는'Post' 나'Reply' 클래스의 경우와 상당히 비슷하며, 원하는대로 체계화되지는 않았지만 여전히 매우 건조한 상태입니다. 또한'(_number-of-posts_) + 1' 대신 단일 쿼리를 실행할 수 있습니다. – Peter