I am trying to create a simple forum in a MVC architecture.
This is my database setup (the relevant part):
Table: forum_categories
`forum_categories` (
`cat_id` INT(8) NOT NULL AUTO_INCREMENT,
`cat_title` VARCHAR(255) NOT NULL,
`cat_desc` TEXT NOT NULL,
PRIMARY KEY (`cat_id`),
UNIQUE KEY (`cat_title`)
Table: forum_topics
`forum_topics` (
`topic_id` INT(8) NOT NULL AUTO_INCREMENT,
`cat_id` INT(8) NOT NULL COMMENT 'foreign key with forum_categories table',
`user_id` INT(11) NOT NULL COMMENT 'foreign key with users table',
`topic_title` VARCHAR(255) NOT NULL,
`topic_desc` TEXT NOT NULL,
`topic_date` DATETIME DEFAULT NULL,
PRIMARY KEY (`topic_id`),
FOREIGN KEY (`cat_id`) REFERENCES forum_categories (`cat_id`) ON DELETE CASCADE ON UPDATE CASCADE
Example of the functionality, I would like to achieve:
Category 1 has cat_id = 1
Category 2 has cat_id = 2
Topic 1 has cat_id = 1
Topic 2 has cat_id = 2
Now when category 1 is selected I just want topic 1 to show.
If category2 is selected I just want topic 2 to show.
This prepared SQL statement achieves that:
PREPARE stmnt FROM
'SELECT *
FROM forum_categories fc
JOIN forum_topics ft ON fc.cat_id = ft.cat_id
WHERE fc.cat_id = ?
ORDER BY ft.topic_date DESC';
SET @a = 1;
EXECUTE stmnt USING @a;
My Problem : I would like to move this functionality into my PHP MVC structure.
Here is my attempt, which does not work (it shows all topics in all categories).
Controller
/**
* Show all the topics in the chosen category
*/
public function showForumTopics()
{
$topic_model = $this->loadModel('Forum');
$this->view->forum_topics = $topic_model->getForumTopics();
$this->view->render('forum/viewTopics');
}
Model
/**
* Gets an array that contains all the forum topics in the database.
* Each array element is an object, containing a specific topic's data.
* @return array All the forum topics
*/
public function getForumTopics($cat_id)
{
$sql = 'SELECT * FROM forum_categories fc JOIN forum_topics ft ON fc.cat_id = ft.cat_id WHERE fc.cat_id = :cat_id ORDER BY ft.topic_date DESC';
$query = $this->db->prepare($sql);
$query->execute(array(':cat_id' => $cat_id));
return $query->fetchAll();
}
View
if ($this->forum_topics) {
foreach($this->forum_topics as $key => $value) {
echo '<p><strong>Title:</strong>' . $value->topic_title . '</p>';
echo '<p><strong>Description:</strong> ' . $value->topic_desc . '</p>';
echo '<p><strong>Author:</strong> ' . $value->topic_author . '</p>';
echo '<p><strong>Date:</strong> ' . $value->topic_date . '</p>';
}
} else {
echo 'No forum topics.';
}
Help would be highly appreciated! Thank you!!
For example, your page http://example.com/?cat_id=2 Your code should be like this
Controller
public function showForumTopics()
{
$default_category = 1;
$topic_model = $this->loadModel('Forum');
$cat_id = isset($_GET['cat_id']) ? $_GET['cat_id'] : $default_category;
$this->view->forum_topics = $topic_model->getForumTopics($cat_id);
$this->view->render('forum/viewTopics');
}
Model
public function getForumTopics($cat_id) {
$sql = 'SELECT * FROM forum_categories fc JOIN forum_topics ft ON fc.cat_id = ft.cat_id WHERE fc.cat_id = :cat_id ORDER BY ft.topic_date DESC';
$query = $this->db->prepare($sql);
$query->execute(array(':cat_id' => $cat_id));
return $query->fetchAll(); }
View
if ($this->forum_topics) {
foreach($this->forum_topics as $key => $value) {
echo '<p><strong>Title:</strong>' . $value->topic_title . '</p>';
echo '<p><strong>Description:</strong> ' . $value->topic_desc . '</p>';
echo '<p><strong>Author:</strong> ' . $value->topic_author . '</p>';
echo '<p><strong>Date:</strong> ' . $value->topic_date . '</p>';
}
} else {
echo 'No forum topics.';
}
Your problem is that your backend requires and ID to pull the specific category (and via the join, the correct topic). In your DB Query, you are looking for it here: WHERE fc.cat_id = ?
Your getForumTopics($cat_id)
function also requires the ID to pass into that prepared statement. Problem is you aren't passing any ID into that function when you call it:
$this->view->forum_topics = $topic_model->getForumTopics();
So without anything coming through, your function is now broken and should be throwing an error. You have two options at this point:
Make a backup that lists all topics when no specific category is chosen. You'd do that with something like this in your function definition:
// Specifying the backup option null here, for when there is no ID passed public function getForumTopics($cat_id = null) { // Simple check for an ID if ($id) { // Run the code you had before $sql = 'SELECT * FROM forum_categories fc JOIN forum_topics ft ON fc.cat_id = ft.cat_id WHERE fc.cat_id = :cat_id ORDER BY ft.topic_date DESC'; $query = $this->db->prepare($sql); $query->execute(array(':cat_id' => $cat_id)); return $query->fetchAll(); } } else { // Otherwise, do the same thing as above but without a WHERE clause } }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.