doureng1083 2019-05-29 23:11
浏览 81
已采纳

php中的mvc模型应该是PDO包装器吗?

I have been trying to learn about MVC pattern (without frameworks), however no matter material I read on the Internet, it just seems to be contradicting itself all the time.

My project right now consists of a form that can be submitted in order to add an element to the database. Another page just lists all the elements that are on the database.

So as I understand, my model should connect to the database (or just take the connection as a parameter, something else that was not very clear to me) and have functions like "saveItem" (which takes the $_POST variable as an input and parses it) and "listItems" (which just returns all entries to the page).

However, where does the controller come in? Now I parse my data in the model. But, if that should be rather done in the controller, what does the model actually do? I came across this page. Here, the model only has methods like "select" whose input is just a sql query. But this seems essentially just a PDO wrapper. (Contradicting information in this page about PDO already being a kind-of wrapper and there isn't really any need to do it.)

I guess it kind of makes sense, if the model was written as just a wrapper, it wouldn't actually have anything to do with the specifics of my website. (My understanding now is that each part of mvc is highly specific for each project.)

But then, it seems that either the model or the controller is just unnecessary. Either model parses the data leaving nothing for the controller to do or vice-versa.

I would be deeply grateful for any clarification.

  • 写回答

2条回答 默认 最新

  • doulu6160 2019-05-30 05:19
    关注

    I'd take this question rather as a genuine inquiry than a request to review some SEO spam article from Internet. So it goes:

    What you need to understand in the first place is that the term "model" is ambiguous. It can represent either the whole application's business logic, or just what you meant - some piece of code that interacts with the database. To avoid this ambiguity, let's stick with the former. It will help you to settle with the Controller. Whereas we will call a "lesser model" a storage. A cover term for a code which actually interacts with the database.

    I have a very concise writeup, MVC in simpler terms or the structure of a modern web-application. It will help you to wrap your head around MVC at whole.

    Now closer to your question.

    A database wrapper cannot be considered a model, in either meaning. A database wrapper is a service used by the storage class. So, you can have at least 3 layers in your application:

    • a controller. Just an interface to convey an HTTP client's request to the business model
    • a service or a helper. the code which is usually (and wrongly) written in the controller. For example, if you need to register a user, in the controller you are calling a method from a user service, providing the data came from the client.
    • a storage class. The actual code to interact with a database. For example it could be a User class that contain methods such as register and such. This class would use PDO (or some more advanced wrapper, or an ORM instance) as a class variable.

    Where the latter two should actually encapsulate your whole application's business logic.

    The most tricky part here is the instantiation of the Storage class. Given the connection must be done only once, there should be means to instantiate the UserStorage object providing it with the database connection. That is slightly different issue which is solved by means of the Dependency Injection Container

    To illustrate the above with a bit of code

    class UserController extends Controller
    {
        public function create($request)
        {
            $userService = $this->serviceContainer->get('user_service');
            $userService->create(
                $request->email;
                $request->password;
            );
        }
    }
    class UserService
    {
        public function create($username, $password)
        {
            // here, userStorage instance was already injected 
            // in the UserService in the controller by DI container
            $this->userStorage->create(
                $request->email;
                $request->password;
            );
        }
    }
    class UserStorage
    {
        public function create($username, $password)
        {
            $sql = "INSERT INTO user VALUES (null, ?, ?)";
            // here, db instance was already injected 
            // in the UserStorage in the controller by DI container
            $this->db->prepare($sql)->execute([$username, $password]);
        }
    }
    

    It could be considered unnecessarily verbose, with all these seeming repetitions, but there are reasons for that:

    1. in the real code there are other parts in the each stage, For example,
      • Controller would validate the form submitted (like whether the form was actually submitted, whether passwords are equal, etc.) and call View to render the form.
      • UserService could perform additional validations, like whether such email already exists
    2. Different calling points
      • UserService could be called from many differnt places: from the above controller or a command line utility, or a REST controller.
      • UserStorage could be called from even more places. For example there is a TaskService that lists tasks belong to users, and it will naturally make a good use of the UserStorage class. And so on.

    So it makes a perfect sense to separate your layers this way.

    Of course it's just an oversimplified draft model, it doesn't implement an ORM which is usually here, and many other things. But the simpler the sketch is, the less details it have, the simpler to get the main idea.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 树莓派启动AP热点传入数据
  • ¥15 multisim中关于74ls192n和DSWPK开关的问题(相关搜索:计数器)
  • ¥15 在误装Windows server2019 后如何利用Windows.old恢复?
  • ¥20 代码实现状态连接包过滤防火墙的设计与实现
  • ¥15 vscode的红色箭头爆红和has no default export报错
  • ¥15 关于#sql#的问题:#情况描述 在用vs对项目进行调试时,出现找不到网络路径,然后查看SQL配置工具,发现SQL服务显示远程调用过程失败(相关搜索:防火墙)
  • ¥15 eNSP中基于默认路由及浮动路由的公司与分部互联和校园网综合项目
  • ¥15 主要进行描述泥浆在管路不同区段泥浆的密度不相同,泥浆的密度有高有低,此时管路的摩阻分布需要怎么计算,(标签-matlab)
  • ¥40 通过编制程序计算圆管内层流充分发展对流换热,参数如图5-4,以及公式5-16所示,要求用表5-6对程序计算准确性进行验证
  • ¥20 该学习哪个编程语言? AI会取代程序员吗?