I am fairly new to OOP PHP
and as I am building my first project, I am coming across some difficult dilemmas.
I'm trying to build a forum. Yes, I know there are many free ones out there, I just want to have one that I can build according to my own needs :). Plus, it's fun to code.
I have build a base model and controller and template, for the forum, thread and post. The base model has standard database functions, like find all, find by id etc. The individual models extend the model class and have only specific functions to the class. I have set it up like this:
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;
}
And besides the decisions that were tough, that I already had to make about certain functions and variables being static or not. I have this dilemma:
The basic CRUD works from the base model. That is fine, I can create, update, delete and read from my database through calling static methods from the (base) model, which instantiates objects for these forum, thread and post models. So far so good.
Part of the 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;
}
}
?>
I transfer these objects for displaying in my templates. When reading from one table, that works just fine.
<?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>
However, for the display of all posts in the threads, I need info from the user table, e.g. there number of their posts, rank, avatar etc.
Okay, so here's the thing:
SELECT * FROM post
LEFT JOIN user ON (post.user_id = user.id)
where thread_id={$id}
ORDER BY date_line DESC
LIMIT {$offset} , {limit}
I now have more fields then variables that I have setup in my Post model. So they are not transferred for displaying.
Should I use an array for displaying these extra fields instead of object? I would rather still use the object approach for displaying, as I am now set up for that.
Or should I maybe add these user fields as variables to my Post model? I am thinking that is not the most tidy way to do it, however it would work.
Or should I go through a foreach
loop to get a separate instance of a (yet to create) user class? I am thinking it would drain much more memory then the Left Join that simply gets me the data that I need.
I would like some hints on how you would solve this.