php mvc真正遵循的关键在于代码边界:model只管业务判断(如密码加密、邮箱校验),controller仅调度(取参、调model、传数据),view纯渲染(禁用超全局变量和数据库操作)。

PHP项目要真正遵循MVC,不是建三个文件夹就完事——关键在代码里每行都守住边界:Model只决定“能不能做”,Controller只问“谁来做、传什么”,View只管“怎么画”。越界一步,后续改需求就得全局搜 $_POST 或 new UserModel()。
Model里该放密码加密还是SQL语句?
放密码加密、邮箱校验、存在性检查,不放裸SQL。Model的核心是业务判断,不是数据库搬运工。
-
UserModel::addUser()必须包含password_hash()、filter_var($email, FILTER_VALIDATE_EMAIL)、$this->existsByUsername() - 数据库操作封装成方法,如
save()、findByEmail(),内部用protected $db持有连接实例,避免每次 new PDO - 禁止在 Model 里
echo、header()、exit或拼接 SQL 字符串——预处理是底线,mysqli_query($conn, "INSERT INTO users...")直接算越界
Controller里写date()或preg_match()算越界吗?
算。Controller 是调度员,不是业务处理器。它只该做三件事:取参、调 Model、传数据给 View。
- 把
date('Y-m-d', $ts)、preg_match('/^1[3-9]\d{9}$/', $phone)塞进 Controller,会导致单文件膨胀、无法单元测试 - 正确做法:抽成独立类,如
TimeFormatter::toChinaDate()、PhoneValidator::isValid(),Controller 只留$user = $this->userModel->create($validatedData) - 参数清洗必须前置:
$request->validated()(Laravel)比手动filter_input()更可靠;漏一次,脏数据就直通 Model
View里能调$_GET或new UserModel()吗?
不能。View 是纯模板,输入只能来自 Controller 显式传递的变量。
- 禁止在
views/user/profile.php里出现$_GET['id']、new UserModel()、file_get_contents()、require - 输出必须过
htmlspecialchars()防 XSS,{{ $user->name }}(Blade)或<?php echo htmlspecialchars($name); ?>是安全底线 - 路径硬编码风险大:用
views/user/edit.php这种固定路径,别拼include $_GET['tpl'] . '.php',防任意文件读取
最难守的其实是 Controller 的“轻量”——它看起来最自由,却最容易变成逻辑垃圾场。一旦你在 UserController.php 里开始写格式化、校验、跳转、日志,MVC 就已经塌了一角。真正的分层,不在目录结构,在每一行代码的归属意识。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











