都是套路,从此不再纠结 Model 和 Controller 的分层
大部分 phper 使用 MVC 模式的时候
可能遇到过这种情况
有些逻辑可写到 controller
也可写到 model
没有一个清晰的界限
写着写着也就会发现
每个人分的都不一样
可能换做你会写到 model 里的
其他队友就会写到 controller
程序是都能运行
但风格总是得不到统一
谁也说服不了谁
总会有一个人不舒服
那 M & C 到底应该怎么分呢?

其实 Model 本意是模型
大部分人会将它用做数据层
其他的都丢 Controller 里面
然而 Model 不应该只是数据操作
也应该包含一定的业务逻辑

也就是说 Model 里
可以写数据操作
也可以写业务逻辑
有人会说这岂不是更乱?
那还要 Controller 做什么?

那么接下来咱们带着疑问看看
Controller 到底应该做什么?

其实所有大部分(可能有例外)
Controller Action 做的事可以分为4步

权限验证
输入过滤
执行操作
返回结果
当中有的步骤可以省略
比方说 1, 2, 4

说白了
Controller 就是用来
控制程序执行流程的
而具体的怎么做
是调用 Model 来处理

比如说

class Controller
{

public function action()
{
    // 1. 权限验证
    Permission::basic();

    // 2. 输入过滤
    $input = User::loginValidate($this->input->post());

    // 3. 执行操作
    $article = User::addArticle($input->title, $input->content);

    // 4. 返回结果
    return User::allArticle();
}

}
然而这里有一个致命的问题
并不是所有的 Action 都是单向的

比如说
常见的用户注册功能

那如何把它变成单向的呢?

我的做法是使用 try catch

class Controller
{

public function action()
{
    // 1. 权限验证
    try {
        Permission::basic();
    } catch(Exception $e) {
        switch($e->getMessage()) {
            case User::NO_PERMISSION:
                return Site::noPermission();  // 显示 403
        }
    }

    // 2. 输入过滤
    try {
        $input = User::registerValidate($this->input->post());
    } catch(Exception $e) {
        switch($e->getMessage()) {
            case Validate::REQUIRED:
                return Redirect::back('用户名不能为空');
            case Validate::CONFIRM:
                return Redirect::back('用户已存在');
        }
    }

    // 3. 执行操作
    try {
        $user = User::register($input->username, $input->password);
    } catch(Exception $e) {
        switch($e->getMessage()) {
            case ...
        }
    }

    // 4. 返回结果
    return $user;
}

}
至此就可以无脑的按照套路来写 MVC 了

此方案只是我的最佳实践
希望能给大家带来一丝灵感就好
可能看起来不是很优雅

优点是可能性很多
因为是重复的流程
比方说弄个 Web GUI
将 Model 的方法弄成各种块
用拖拽的形式来生成 Controller

文章来源:http://zhijia.io/?from=groupmessage#/article/101213
如果觉得好,请支持原作者!

最后由 Leo 编辑于2016年11月03日 09:01