【问题标题】:PHP MVC: Share model between controller and viewPHP MVC:在控制器和视图之间共享模型
【发布时间】:2017-05-08 19:23:44
【问题描述】:

我正在开发我的 PHP (H)MVC 项目,在该项目中我将视图与控制器分开 - 如答案 How should a model be structured in MVC? 所示。他们的关系是1:1,所以他们有相同的“动作”。因此,在 bootstrap.php 中,实例化它们后,我调用:

// ... Controller and view are already instantiated.
call_user_func_array(array($controller, $actionName), $actionParameters);
call_user_func_array(array($view, $actionName), $actionParameters);

假设一个控制器和一个视图分别成为一个模型(域对象)作为构造函数参数。 使用Auryn 依赖注入容器,我尝试在控制器和视图之间共享同一个模型实例,而不事先实例化它。例如。在 bootstrap.php 中进行控制器和视图实例化之前。

tereško 在他的回答中描述了模型/服务工厂的使用。但作为“注”,他说:

...更好的实现将有 DI 容器(如 Auryn) 来创建控制器和视图,只需要 服务,而不是使用工厂。

我的问题是:我可以在没有模型工厂的情况下使用依赖注入容器来实现此功能吗? 我有点卡在这项任务中,我真的不知道这是否可能。 谢谢。

【问题讨论】:

    标签: php design-patterns model-view-controller model service-layer


    【解决方案1】:

    是的,你可以。

    但这有点繁琐。您基本上需要将服务设置为“共享”:

    <?php
    $injector->define('MailerService', [
        ':server' => 'fak.it',
        ':port' => '443',
    ]);
    $injector->share('MailerService');
    
    $controller = $injector->make('FooBarController');
    

    这假设你的控制器是这样定义的:

    <?php
    class FooBarController 
    {
        public function __construct(MailerService $service) 
        {
            // ...
        }
    }
    

    在这方面,Symfony 的独立 DI component 更易于使用,因为您可以将这种配置放在 json 或 yaml 文件中。

    P.S. 您可能应该将您的用户输入抽象为某种Request 对象,然后在每次方法调用时将其传递到您的控制器中。

    有点像这样:

    <?php
    $request = new Request( .. something here maybe .. );
    $controller->action($request);
    

    制作更好看的代码:)

    【讨论】:

    • 谢谢,@tereško。你的解决方案就是一个!我测试了它,它工作得非常好。至于 Auryn - 将 other 对象(如Request)注入方法中,以及通过路由传递的动作参数:它不是看起来很简单——如果在自动调用 C/V 动作和没有路由定义的情况下不是不可能的话。我通过视图模型层 (MVVM+C) 使我的项目更进一步,我将在我的板上以某种方式分享我的所有经验。 PS:您对 MVC 原则的介绍让所有 MVC 开发人员都变得更好;-)
    • 你误会了一点。如果您使用的是“调度路由器”(例如FastRoute,您可以在其中精确定义要传递的参数和顺序,则只有才能传递确切的操作参数。否则,您放松对参数传递顺序的所有控制。(续)
    • 如果您不使用“调度路由器”(如Symfony's routing component),最好以Request 实例的形式传递抽象。然后在控制器的方法中使用它来调用$request-&gt;get('parameter_name')
    • 致@tereško,完成:我的GET请求格式为:Module/Controller/action/[arg1]/.../[argN]?oper=read&amp;page=7&amp;...“动作”接受arg1,...,argN作为参数并从@读取operpage值987654335@,至少到目前为止,它被注入到 C/V 构造函数中。
    • 我明白了。所以,@tereško,假设没有路由调度程序,您是否建议传递 JUST 一个 Request 实例作为操作参数,而不传递 url 值?比如:search(Request $request) 而不是 search(Request $request, $arg1, $arg2)search($arg1, $arg2)。对吗?
    猜你喜欢
    • 2012-02-16
    • 2018-08-29
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    相关资源
    最近更新 更多