所以,我正在构建我的第一个基于MVC的应用程序。
我遵循了本教程:requiremind.com/a-most-simple-php-mvc-beginners-tutorial/现在我正在根据上述教程创建论坛。
这是在我的index.php
中if(isset($_GET['controller']) && !isset($_GET['action'])) {
$controller = $_GET['controller'];
$action = 'topic';
} else {
$controller = 'main';
$action = 'index';
}
第一个条件是显示带有主题的页面,并且对于带有?controller = PHP或类似内容的网址有效,并将$ action设置为' topic'。
现在请求将转移到routes.php
function call($controller, $action) {
require_once('controllers/main_controller.php');
if($controller == 'main') {
require_once('models/main_model.php');
$controller = new MainController();
} else {
require_once('models/topic_model.php');
$controller = new MainController();
}
$controller->$action();
}
$db = Db::getInstance();
$query = $db->query('SELECT cat_name FROM category');
$categories = $query->fetchAll();
foreach($categories as $category_name) {
if($controller == $category_name && $action == 'topic') {
call($controller, $action);
}
}
if(($controller == 'main') && ($action == 'index')) {
call($controller, $action);
}
现在这将向数据库发出请求,如果主题/类别存在,它将调用该函数。
main_controller.php
class MainController {
public function index() {
$category = Main::home();
require_once('views/home.php');
}
public function topic() {
$topics = Topic::thread_topic($_GET['controller']);
require_once('views/topic.php');
}
}
在main_controller.php之后,topic_model.php:
<?php
class Topic {
public $thread_topic;
public $thread_desc;
public $thread_created_at;
public $thread_created_by;
public $category_id;
public function __construct($thread_topic, $thread_desc, $thread_created_at, $thread_created_by, $category_id) {
$this->thread_topic = $thread_topic;
$this->thread_desc = $thread_desc;
$this->thread_created_at = $thread_created_at;
$this->thread_created_by = $thread_created_by;
$this->category_id = $category_id;
}
public function thread_topic($controller) {
$list = [];
$cat_id = Fnct::cat_name_to_id($controller);
$db = Db::getInstance();
$stmt = prepare('SELECT * FROM thread WHERE thread_created_by =:cat_id');
$stmt->execute(array(':cat_id' => $cat_id));
foreach($stmt->fetchAll() as $thread) {
$list[] = new Topic($thread['thread_topic'], $thread['thread_desc'], $thread['thread_created_at'], $thread['thread_created_by'], $thread['category_id']);
}
return $list[];
}
}
?>
现在是views / topic.php
<table border='1'>
<tr>
<th>Thread Topic</th>
<th>Thread Desc</th>
<th>Thread Started At</th>
</tr>
<tr>
<?php foreach($topics as $topic) { ?>
<td><?php echo $topic->thread_topic; ?></td>
<td><?php echo $topic->thread_desc; ?></td>
<td><?php echo $topic->thread_created_at; ?></td>
<?php } ?>
</tr>
</table>
问题是这样,它显示空白页面。并且没有错误。
我仍然在努力弄清楚这里有什么问题。请告诉我这里我做错了什么?
编辑:在routes.php中,在if语句下移动$ controller = new MainController()。但仍然显示相同的空白页面。
答案 0 :(得分:0)
好吧,你的错误发生在你的routes.php中,如上所述。我将尝试在答案中解释它,并直接修复你所犯的错误。
好的,让我们开始吧。首先,让我们先忽略call()
函数,然后再看另一部分:
您的代码:
$db = Db::getInstance();
$query = $db->query('SELECT cat_name FROM category');
$categories = $query->fetchAll();
foreach($categories as $category_name) {
if($controller == $category_name && $action == 'topic') {
call($controller, $action);
}
}
if(($controller == 'main') && ($action == 'index')) {
call($controller, $action);
}
您应该知道fetchAll()
将始终返回arrqay而不是字符串,这就是为什么您无法直接将结果与字符串进行比较的原因。 将代码更改为:
$db = Db::getInstance();
$query = $db->query('SELECT cat_name FROM category');
$categories = $query->fetchAll();
foreach($categories as $category_name) {
if($controller == $category_name["cat_name"] && $action == 'topic') {
call($controller, $action);
}
}
if(($controller == 'main') && ($action == 'index')) {
call($controller, $action);
}
您看到$categoriy_name["cat_name"]
- 您必须提供密钥,因为$category_name
是一个数组,而不是字符串。 (可以看一些PHP和SQL的教程,比如所有的fetch方法是如何工作的以及它们的输出是什么)。
然后是第二部分,你的通话功能
您的代码:
function call($controller, $action) {
require_once('controllers/main_controller.php');
$controller = new MainController();
if($controller == 'main') {
require_once('models/main_model.php');
} else {
require_once('models/topic_model.php');
}
$controller->$action();
}
因此,您将$controller
作为参数传递给该函数。多数民众赞成。但是你分配$controller = new MainController();
所以$ controller不再是你传递给函数的字符串,而是现在是一个MainController类的对象。所以你放弃了传递给函数的价值。然后你只做了1行:
if($controller == 'main') {
这永远不会成真。此时$controller
是mainController()的对象,并且参数将始终求值为false,因此您将始终加载topic_model.php
,因为您的topic()
函数位于MainController内( )没关系,但它不是MVC的用途。那只是..那里有一些随机代码。那不是MVC,也不是好的做法。
但是,我不知道你想用你的主控制器做什么,我不打算深入研究这个话题。随着foreach-loop的更改,调用应该起作用,并且应该加载您的视图。
你不希望像MainController这样的东西总是被拉,或者至少不是你内部的那些方法 - 可能会在MVC上查找一些教程。您只想为您所在的特定部分加载控制器。
无论如何,我祝你未来一切顺利,编码愉快! :)