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
相关产品推荐
相关产品推荐

