控制器和模型之间的MVC类

时间:2018-08-09 20:44:16

标签: php model-view-controller phalcon

我正在Phalcon PHP中构建应用程序,在那里我可以通过网站和API访问数据库。

在普通网站上,我会在此处创建MVC:

- app
-- controllers
-- models
-- views
- public

但是我对于API和Web的重复代码有疑问。

示例代码:

class Users extends Model {
    // ...
    protected $id;
    protected $username;
    protected $email;
    // setters and getters, validation
}

class UserController extends ControllerBase {
    // ...
    public function loginAction() {
        if ($this->request->isPost()) {
            // ... get post
            // check login is correct
            // create session
            // redirect
        }
        $this->view->var = $var;
    }
}

class ApiController extends ControllerBase {
    // ...
    public function loginAction() {
        if ($this->request->isPost() //or put) {
            $json = $this->request->getJsonRawBody();
            // ... get json
            // check login is correct
            // create session
        }
        $response->setStatusCode('2xx/4xx', 'msg');
        $response->setJsonContent([
            'status' => 'OK / ERROR',
            'message' => '$msg / $ex->getMessage()'
        ]);
    }
}

现在,我将创建带有逻辑的类,以检查用户数据是否正确。 我考虑这样的课程:

class MyClass extends ParentClass {
    public function login($username, $password) {
        $user = Users::findFirstByEmail($email);
        if ($user->password === hash($password)) {
            $successLogin = new UserSuccessLogins();
            $successLogin ->setId('id');
            $successLogin ->setIpAddress('ip');
            $successLogin ->save();
        } else {
            $failedLogin = new UserFailedLogins();
            $failedLogin->setId('id');
            $failedLogin->setIpAddress('ip');
            $failedLogin->save();
        }
    }
}

现在我可以在像这样的控制器中使用它:

class UserController extends ControllerBase {
    public function loginAction() {
        if ($this->request->isPost()) {
            $c = new MyClass();
            if ($c->login($username, $password)) {
                // redirect
            } 
        }
        $this->view->var = $var;
    }
}

class ApiController extends ControllerBase {
    public function loginAction() {
        if ($this->request->isPost() //or put) {
            $c = new MyClass();
            if ($c->login($username, $password)) {
                // send json OK
            } else {
                // send json Error
            }
        }
    }
}

什么是最好的方法?我不要模型类中的逻辑。 我已经阅读了有关插件和组件的信息,但是我不知道如何创建良好的自我注释代码。

3 个答案:

答案 0 :(得分:1)

您可能正在寻找Phalcon Multimodule,请看this example。除了“前端”和“后端”模块外,您还可以添加“ API”模块。

答案 1 :(得分:0)

好的,我将使用以下组件扩展我的项目:

-app
--components
--controllers
--models
--views
-public

现在,我的代码可能如下所示:

use Phalcon\Mvc\Model;
class Users extends Model {
    // ...
    protected $id;
    protected $username;
    protected $email;
    // setters and getters, validation
}

use Phalcon\Mvc\User\Component;
class UserComponent extends Component {
    // class with access to dependecy injector
    public login ($email, $password) {
        $user = Users::findFirstByEmail($email);
        // logic with setting session in $di
    }
}

class UserController extends ControllerBase {
    public function loginAction() {
        if ($this->request->isPost()) {
            $userComponent = new UserComponent();
            if ($userComponent ->login($username, $password)) {
                return $this->response->redirect($this->url->getBaseUri(), false, 301);
            } else {
                $this->flash->error('message');
            }
        }
        // setting view variables if not post or login filed
        $this->view->var = $var;
    }
}


class ApiController extends ControllerBase {
    public function loginAction() {
        if ($this->request->isPost()) {
            $userComponent = new UserComponent();
            if ($userComponent ->login($username, $password)) {
                //json OK
            } else {
                //json Error
            }
        }
    }
}

如果没有人有更好的主张,我将在几天之内解决这个问题。

答案 2 :(得分:0)

您的建议是一个不错的选择,但是,如果您想以更好的方式分离和分离职责,则可以尝试使用示例https://github.com/phalcon/mvc/tree/master/multiple-service-layer-model这样的服务层。您将在哪里:

  • 实体(由Phalcon生成的模型)
  • 存储库(所有需要提取,更新或保留数据的操作)
  • 服务(业务逻辑所在)。

此调用图可以总结如下:

控制器->服务->存储库->实体

请注意,依赖关系是一个单一的方向,但是对于简单的任务,您可以在控制器内部直接使用存储库或在服务内部的实体上使用存储库,这取决于您的体系结构有多困难或有多灵活。

我希望这是问候。