mvc是需主动遵循的分工规则:model负责业务判断(如密码加密、邮箱校验),controller仅调度(接收参数、调用model、传值给view),view纯渲染且禁用副作用代码。

MVC不是PHP自带的语法,而是你必须主动组织、约束自己写法的一套分工规则——不按Model处理业务、View只负责渲染、Controller只做调度,框架就只是个空壳。
Model里该放密码校验还是SQL语句?
放密码校验,不放裸SQL语句。Model的核心任务是“决定能不能做”,比如用户注册时,UserModel::addUser() 必须包含:password_hash() 加密、filter_var($email, FILTER_VALIDATE_EMAIL) 校验邮箱、查库确认用户名是否已存在。这些逻辑一旦挪到 Controller 或 View 里,后续加双因素认证或改密码策略时就得满项目搜 $_POST['password']。
常见错误现象:UserController.php 里直接写 mysqli_query($conn, "INSERT INTO users..."),Model 类只剩一个空 class UserModel {};
正确做法:Model 内部用 protected $db 持有连接实例,所有数据库操作封装成方法,如 save()、existsByUsername();
注意点:Laravel 的 Eloquent 或 ThinkPHP 的 Db::insert() 是工具,不是免责条款——它们不替你做业务判断,只帮你发 SQL。
View里能调用$_GET或new UserModel()吗?
不能。View 是纯模板,输入只能来自 Controller 显式传递的变量。一旦你在 user/profile.php 里写 $_GET['id'] 或 new UserModel(),就等于绕过整个 MVC 流程。
安全影响:未加权限判断就输出 $user->password_hash,或者在模板里拼接 SQL 导致注入;
实操建议:extract($data) 或 Blade 的 {{ $user->name }} 是安全传值方式;禁止在 View 文件中出现 new、require、query、file_get_contents() 等任何副作用代码;
性能提示:View 中执行数据库查询会阻塞整个响应,且无法被缓存层(如 Redis 页面缓存)覆盖。
Controller里写正则匹配和时间格式化算越界吗?
算。Controller 是调度员,不是业务处理器。它该做的事只有三件:接收请求参数、调用 Model 方法、把结果交给 View。把 preg_match()、date('Y-m-d', $ts)、array_filter() 塞进 Controller,会导致文件迅速膨胀到 500 行以上,且无法被单元测试覆盖。
参数差异:Laravel 的 $request->validated() 自动过滤并返回清洗后数据,而原生框架常需手动调用 filter_input(),漏掉一次就可能让脏数据进 Model;
可拆分方案:把时间转换逻辑抽成 TimeFormatter 类,正则校验封装为 PhoneValidator,Controller 只保留 $user = $this->userModel->create($validatedData) 这类高阶调用;
容易踩的坑:在 index.php 或路由闭包里直接处理业务,等于把 Controller 职责降级为脚本入口。
为什么MVC最难的部分不是写代码,而是每次动笔前问自己一句?
因为真正难的不是分三层,而是每次写新功能时都得问一句:“这段代码放在哪一层才不会让别人接手时想删库跑路。”Model 决定“能不能做”,Controller 决定“要不要做”,View 只负责“做成什么样”——顺序错了,整个流程就失去约束力。没有测试、没有约定、没有 Code Review,MVC 很快就会退化成带文件夹的 spaghetti code。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











