必须用D方法而非M方法,因D加载自定义模型类以启用验证等逻辑,M仅直连数据库不读取Model文件;D找不到类时降级为M,但M永不加载模型。

在ThinkPHP开发中,遇到表单提交要校验字段、关联数据要自动处理、或跨项目调用模型时,直接用M('User')会报错或跳过验证逻辑——这不是代码写错了,而是你该用D方法而不是M方法。
核心区别一句话说清
M方法是“按表名直连数据库”,参数就是数据表名(如'user'→操作think_user表),不加载任何自定义模型类;D方法是“按类名加载模型”,参数对应Lib/Model/UserModel.class.php这类文件名,必须存在且命名规范,否则抛出异常或退化为M行为。
【D方法找不到对应模型类时会自动降级调用M方法,但M方法永远不读取你的Model文件】
什么时候必须用D方法
第一步:打开你的Lib/Model/UserModel.class.php,确认里面已定义了_validate数组或create()中启用了自动验证;
立即学习“PHP免费学习笔记(深入)”;
第二步:在控制器里写$user = D('User');,然后调用$user->create($_POST);
第三步:如果title字段为空,系统会直接返回错误信息“请输入标题”——这个拦截发生在数据入库前,靠的就是D方法加载的模型类里定义的规则;
若此时换成$user = M('User');,create()仍可执行,但所有_validate配置完全失效,空标题会直接插入数据库,后续只能靠手动判断或数据库约束兜底。
什么时候优先选M方法
方法一:只做简单查询或批量写入,比如后台导出用户列表、定时清理日志表;
方法二:操作临时表、视图或第三方数据库表,这些表根本没配Model类,也不需要验证;
方法三:性能敏感场景,例如高并发商品库存扣减,避免加载额外模型类带来的IO和解析开销。
这一步操作起来很简单,直接$log = M('system_log');→$log->add(['msg'=>'xxx']);即可,无需建任何Model文件。
高级用法与避坑点
方法一:跨项目调用模型必须用D,格式为D('Admin.User')或D('User', 'Admin'),M方法不支持该语法;
方法二:想复用公共逻辑又不想每个表都建Model,可用M('CommonModel:User'),它等效于new CommonModel('User'),前提是CommonModel.class.php已存在并继承Model;
【注意:M方法中表名参数会自动转为小写,若数据库表名含大写字母(如UserOrder),必须显式设置$trueTableName属性,且只能通过D方法实例化后生效】
方法三:D方法有单例机制,同一请求中多次D('User')不会重复实例化;M方法同理,但两者互不影响——D('User')和M('User')生成的是两个完全独立的对象。



















