0

Я строю сайт с CodeIgniter, а у меня есть модель под названием Blog_model.OOP, MVC - Модели и объекты

В пределах Blog_model есть способы вытащить список сообщений по определенной теме, например getPopularPosts().

getPopularPosts() запрашивает таблицу сообщений для списка сообщений с topic_id, соответствующих указанному, и сортирует их по популярности. Итак, это один запрос ко всей таблице сообщений (предположим, что это будет очень большой), чтобы найти все сообщения с topic_idx.

Затем foreach результат as индивидуальный идентификатор сообщения, он создает новый объект Post. Класс Post создает сообщение, устанавливая поле id.

Чтобы вернуть содержимое Post, я назначаю $post->getPost();, который снова запрашивает таблицу сообщений, чтобы вернуть всю строку для заданного id.

Эта организация (AFAIK) следует за хорошим объектно-ориентированным принципом. Но теперь, для каждого сообщения (опять же, давайте предположим, что тысячи, миллионы, независимо ...), я должен сначала запросить список id, а затем снова получить содержимое каждого сообщения. Если я возвращаю 30 сообщений, это означает 31 отдельный запрос.

В качестве альтернативы, я мог бы нарушить объектно-ориентированный шаблон и тянуть * для каждого поста в posts, где topic_id = х. Затем у меня есть один запрос, который возвращает все 30 сообщений, но теперь я не чувствую себя объектно-ориентированным.

Что делать?

+0

Считаете ли вы, что важно «чувствовать себя объектно-ориентированным»? - Если вас беспокоит производительность или что-то в этом роде, вы можете запустить этот запуск в фоновом режиме как полностью оговоренный в процессе изменения и записать результаты в плоские текстовые файлы. Тогда вам даже не нужно запускать запросы для каждого сообщения, вы можете просто использовать идентификатор из исходного запроса для отображения результатов из кэшированного файла. Но если вы ищете комментарий, который выбирает один из вариантов, о котором вы упомянули, я бы пошел с объединенным запросом. Код воспламенителя, если я не ошибаюсь, не является строго оо. Кохана, я думаю, есть, и у них есть ORM, чтобы делать то, что вы хотите. –

+0

Если это имеет значение, это CodeIgniter 2. – Peter

+0

В вашем вопросе есть много информации, пожалуйста, дайте конкретные примеры того, о чем вы говорите, если хотите, чтобы они были правильно рассмотрены здесь. – jondavidjohn

ответ

3

Нет причин иметь столько запросов. Вы просто ищете 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

Но в духе ООП (и, может быть, это означает отсутствие леса для деревьев), не было бы более «правильным» поставить такую ​​логику в класс «Почта»? Потому что, может быть, я хочу получить ответы на конкретную запись. С помощью вашего метода это ставит 'getPost()' и 'getReplies()' под одним и тем же классом; тогда как мне кажется, что 'getReplies()' должен быть методом класса 'Post'. – Peter

+1

Да, я думаю, что вы полностью упускаете лодку по тому, что на самом деле означает ООП и как ее реализовать ... Если вы собираетесь получать ответы на одну запись, это должна быть другая функция в модели blog_posts и только запрос для конкретного идентификатора блога ... если вы собираетесь получать несколько ответов для нескольких сообщений, тогда вы собираетесь искать несколько mysql JOIN. Простой способ сказать, что ваша цель должна состоять в том, чтобы выполнить то, что вам нужно, используя наименьшее количество запросов, насколько это возможно. ООП - это всего лишь способ сделать все, чтобы вы организовали. – tgriesser

+0

Стоит упомянуть, что изначально у меня были все, что вы описали. Основываясь на вашем ответе, я вернулся к этой настройке. Общий вес кода довольно схож с тем, что он будет с классами «Почта» и «Ответ», и хотя все не так организовано, как хотелось бы, оно все еще очень СУХОЙ. Кроме того, я могу запустить один запрос вместо '(_number-of-posts_) + 1'. – Peter

Смежные вопросы