Должен ли я создать объект или работать с массивом?

Я довольно новичок в OOP PHP и по мере того, как я строю свой первый проект, я сталкиваюсь с некоторыми сложными дилеммами.

Я пытаюсь создать форум. Да, я знаю, что там много свободных, я просто хочу иметь тот, который я могу построить в соответствии со своими собственными потребностями :). Плюс, это весело кодировать.

Я создал базовую модель, контроллер и шаблон для форума, темы и сообщения. Базовая модель имеет стандартные функции базы данных, такие как поиск всех, поиск по идентификатору и т. Д. Отдельные модели расширяют класс модели и имеют только определенные функции для класса. Я настроил это так:

 class Post_Model extends Model { static protected $_table_name = 'post'; static protected $_db_fields = array('id', 'thread_id', 'parent_id', 'username', 'user_id', 'title', 'date_line', 'pagetext', 'show_signature', 'ip_address', 'icon_id', 'visible'); /** * @var db fields */ public $id; public $thread_id; public $parent_id; public $username; public $user_id; public $title; public $date_line; public $pagetext; public $show_signature; public $ip_address; public $icon_id; public $visible; } /* * joined fields with user object. needed to display posts in all details */ static public function get_posts($id, $limit, $offset){ $result_set = static::find_by_sql(" SELECT * FROM post LEFT JOIN user ON (post.user_id = user.id) where post.thread_id=".(int)$id." ORDER BY date_line DESC LIMIT {$offset} , {$limit}"); return !empty($result_set) ? $result_set : false; } 

И помимо решений, которые были жесткими, я уже должен был сделать некоторые функции и переменные статическими или нет. У меня есть эта дилемма:

Основной CRUD работает от базовой модели. Это нормально, я могу создавать, обновлять, удалять и читать из своей базы данных, вызывая статические методы из (базовой) модели, которая создает объекты для этих форумов, потоков и почтовых моделей. Все идет нормально.

Часть Model Class :

  <?php /** * Find rows from database based on sql statement * @param string $sql * @retun array $result_set */ static public function find_by_sql($sql = '') { $db = Database::getInstance(); $mysqli = $db->getConnection(); $result = $mysqli->query($sql); $object_array = array(); while ($record = $result->fetch_array()) { $object_array[] = static::instantiate($record); } return $object_array; } private static function instantiate($record) { $object = new static; foreach ($record as $attribute => $value) { if ($object->has_attritube($attribute)) { $object->$attribute = $value; } } return $object; } } ?> 

Я переношу эти объекты для отображения в своих шаблонах. При чтении из одной таблицы это работает отлично.

  <?php $postcount = $pagination->offset + 1; if (!empty($posts)) { foreach ($posts as $post) { ?> <div class="post"> <div class="posttime"><?php echo strftime("%A %e %B %G %H:%M", $post->date_line); ?></div> <div class="postnumber">#<?php echo $postcount; ?></div> <div class="postuser"> <div class="username"><?php echo $post->username; ?></div> <div class="avatar">avatar</div> </div> <div class="postcontents"> <div class="posttext"><?php echo $post->pagetext; ?></div> </div> </div> <?php $postcount++; } ?> <div class="pagination"><?php echo $page_split; ?></div> 

Тем не менее, для отображения всех сообщений в потоках мне нужна информация из таблицы пользователя, например, количество их сообщений, ранга, аватара и т. Д.

Ладно, вот что:

 SELECT * FROM post LEFT JOIN user ON (post.user_id = user.id) where thread_id={$id} ORDER BY date_line DESC LIMIT {$offset} , {limit} 

Теперь у меня есть больше полей, чем переменные, которые у меня установлены в моей модели Post. Поэтому они не передаются для отображения.

Должен ли я использовать массив для отображения этих дополнительных полей вместо объекта? Я предпочел бы использовать объектный подход для отображения, так как я сейчас настроен для этого.

Или я могу добавить эти поля пользователя в качестве переменных в мою модель Post? Я думаю, что это не самый аккуратный способ сделать это, однако это сработает.

Или мне нужно пройти через цикл foreach чтобы получить отдельный экземпляр класса пользователей (но для создания)? Я думаю, что это истощило бы намного больше памяти, чем Left Join, что просто доставит мне нужные мне данные.

Я хотел бы получить некоторые подсказки о том, как вы это решаете.

Вы не сможете решить эту проблему с помощью своей схемы, потому что вы смешиваете свойства разных объектов в Post объекте [т.е. имя пользователя].

Идея состоит в том, что вам просто нужно, чтобы ваш код знал о взаимоотношениях между сущностями, например:

 class Post extends Entity { protected $id; protected $body; protected $date; // this will be an instance of a Thread entity, let's say protected $thread; // this will be an instance of the User entity protected $user; ... } 

Таким образом вы сможете:

 $somePost -> getUser() -> getAvatar(); 

Но как вы вводите правильный пользователь и поток в каждый пост? Это то, к чему относятся реляционные сопоставления объектов : в вашем случае все элементы SQL обрабатываются ORM, и вы будете просто иметь дело с графом объектов, без каких-либо проблем с построением запросов самостоятельно; вам просто нужно определить такие отношения.

Популярным PHP ORM является Doctrine : вот пример того, как он обрабатывает объявления отношений .

Разумеется, этот подход имеет свои недостатки, но вам предстоит исследовать и найти наилучший компромисс между гибкостью и зависимостями.

Одна вещь, которая может нарушить дилемму; в PHP объект может также действовать как массив (или даже функция !), но обычный обычный массив не может иметь свойств или любой другой функции ООП.