You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MVC架构下控制器向视图传递变量失败的技术求助

在MVC架构中实现控制器到视图的变量传递(下拉菜单场景)

我想把数据从控制器传递到视图的下拉菜单中,非MVC架构下代码能正常运行,但不清楚MVC架构里怎么实现控制器到视图的变量传递,相关代码如下:

数据读取类(ReadCategories)

class ReadCategories {
    private $db;

    public function __construct($pdoConnection) {
        $this->db = $pdoConnection;
    }

    public function getCategories() {
        try {
            $query = $this->db->prepare("SELECT * FROM categories");
            $query->execute();
            return $query->fetchAll(PDO::FETCH_ASSOC);
        } catch (PDOException $e) {
            error_log("Error fetching categories: " . $e->getMessage());
            return [];
        }
    }
}

控制器类(CategoryController)

class CategoryController {
    private $readCategories;

    public function __construct(ReadCategories $readCategories) {
        $this->readCategories = $readCategories;
    }

    public function handleRequest() {
        session_start();

        if (!isset($_SESSION['username']) || empty($_SESSION['username'])) {
            header("Location: /technique-db/app/MVC/View/LoginView.php");
            exit();
        }

        $categories = $this->readCategories->getCategories();

        include __DIR__ . '/../View/AddItemsView.php';
    }
}

路由与初始化代码

$pdoConnection = require __DIR__ . '/../Config/db.php'; // 引入数据库连接文件并获取PDO连接

// 检查数据库连接是否为有效的PDO实例
if (!$pdoConnection instanceof PDO) {
    echo "Database connection failed.";
    exit(); // 如果连接失败则终止脚本
}

$readCategories = new ReadCategories($pdoConnection);

// 路由到CategoryController
if (isset($_GET['action']) && $_GET['action'] === 'additems') {
    $categoryController = new CategoryController($readCategories);
    $categoryController->handleRequest();
    exit();
}

// 登录相关初始化
$loginUser = new LoginUser($pdoConnection);
$indexController = new IndexController($loginUser);
$indexController->handleRequest();

实现控制器到视图的变量传递

你的代码其实已经具备了变量传递的基础——控制器中获取的$categories变量,在include视图文件后,视图可以直接访问这个变量。只需要在AddItemsView.php中编写下拉菜单的渲染代码即可:

<!-- AddItemsView.php 中的下拉菜单代码 -->
<select name="category_id">
    <option value="">请选择分类</option>
    <?php foreach ($categories as $category): ?>
        <option value="<?= htmlspecialchars($category['id']) ?>">
            <?= htmlspecialchars($category['name']) ?>
        </option>
    <?php endforeach; ?>
</select>

更规范的MVC变量传递方式(可选)

如果想让代码更符合MVC的解耦原则,可以选择以下两种方式优化:

方式1:封装变量数组

修改控制器中的include逻辑:

// CategoryController的handleRequest方法中
$data = [
    'categories' => $this->readCategories->getCategories()
];
include __DIR__ . '/../View/AddItemsView.php';

视图中通过$data['categories']访问:

<select name="category_id">
    <option value="">请选择分类</option>
    <?php foreach ($data['categories'] as $category): ?>
        <option value="<?= htmlspecialchars($category['id']) ?>">
            <?= htmlspecialchars($category['name']) ?>
        </option>
    <?php endforeach; ?>
</select>

方式2:使用视图类

创建一个基础视图类:

class View {
    private $data = [];

    public function assign($key, $value) {
        $this->data[$key] = $value;
    }

    public function render($viewPath) {
        extract($this->data); // 将数组键转为变量名
        include $viewPath;
    }
}

控制器中使用视图类:

// CategoryController的handleRequest方法中
$view = new View();
$view->assign('categories', $this->readCategories->getCategories());
$view->render(__DIR__ . '/../View/AddItemsView.php');

视图中依然可以直接使用$categories变量,和基础写法一致。

内容的提问来源于stack exchange,提问作者William

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 03:27:19