我在这里做错了什么?

时间:2018-02-07 07:41:08

标签: php

所以,我正在构建我的第一个基于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()。但仍然显示相同的空白页面。

1 个答案:

答案 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上查找一些教程。您只想为您所在的特定部分加载控制器。

无论如何,我祝你未来一切顺利,编码愉快! :)