Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/254.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 我可以从视图调用模型吗?_Php_Model View Controller - Fatal编程技术网

Php 我可以从视图调用模型吗?

Php 我可以从视图调用模型吗?,php,model-view-controller,Php,Model View Controller,我没有使用成熟的PHP MVC,而是设计了一个最适合我使用的。我已经完成了基本框架,并编写了运行我的网站所需的模型和控制器 现在我进入视图,我遇到了一个小难题。我的方法对我来说很有效,但为了将来的参考,我想知道我所做的是不是一个坏习惯 我想做什么: 在我看来,我正在调用运行身份验证系统的模型,并请求用户的登录状态。然后,我使用该布尔值来决定是否在视图中显示某些元素,以及将其他元素放置在何处 我应该为每个登录状态设计单独的视图,还是这种方法可以?然而,如果我要在为我的客户所做的工作中实现这个MVC

我没有使用成熟的PHP MVC,而是设计了一个最适合我使用的。我已经完成了基本框架,并编写了运行我的网站所需的模型和控制器

现在我进入视图,我遇到了一个小难题。我的方法对我来说很有效,但为了将来的参考,我想知道我所做的是不是一个坏习惯

我想做什么:

在我看来,我正在调用运行身份验证系统的模型,并请求用户的登录状态。然后,我使用该布尔值来决定是否在视图中显示某些元素,以及将其他元素放置在何处

我应该为每个登录状态设计单独的视图,还是这种方法可以?然而,如果我要在为我的客户所做的工作中实现这个MVC,我需要使用最佳实践


任何建议都将不胜感激

虽然我对MVC的了解还不够多,这会给我自己带来麻烦,但我一直认为,除非你的视图是严格意义上的用户界面,否则它就不应该存在

此外,我还提出了瘦控制器、胖模型的想法


除此之外,我建议在身份验证系统模型中添加一个方法,该方法返回要渲染的适当视图并将其传递给视图。

好的,我会尽可能地保持视图的逻辑自由。如果需要根据模型方法的结果等切换任何内容,请将代理渲染的控制器放置到位

只要确保你遵循基本的想法:在模型中完成你的工作,告诉你的模型从你的控制器中做什么,同时告诉你的视图从你的控制器中显示什么

你可以,但你不应该。除了一些极端情况(并且基于登录状态分支视图肯定不是“极端情况”),从视图调用模型通常都不是一个好主意

在这种情况下,您可能需要通过控制器将布尔值传递给视图。这样,如果您更改了有关用户模型的某些内容,只要控制器保持相同的行为,视图就不必知道

我可以从视图调用模型吗

可以。只要保持M、V和C之间的关注点分离,就可以从视图中自由调用模型(或控制器)。大多数MVC图至少显示视图和模型之间的双向连接。但是,您不想做的是将模型(或控制器)中的逻辑/代码放到视图中,而不想从视图中修改模型

例如,您的页面上可能有一个小部件,它可以在您的网站的每个页面上聚合来自您最喜爱的博客的最新十篇博客文章的标题。您可以通过调用,比如说
MyFavFeeds::getLatest(),获得标题在您的模型中。你现在有什么选择

  • 您可以添加代码以将标题提取到控制器中,但这将要求您在每个控制器操作中复制它,这违反了DRY原则。此外,控制器关心的是处理特定操作的用户输入,获取每次调用的标题甚至可能与这些操作无关
  • 如果您的体系结构支持它,您可以在某种preDispatch钩子中获取该数据,也就是说,从插件或回调加载标题并将其注入视图。这将是枯燥的,但第二个开发人员可能不知道该插件,并意外地覆盖了包含其控制器操作标题的变量。在某些情况下,您可能不想加载标题,例如,当只呈现表单提交的确认页面时,因此您必须有禁用插件的机制。这需要考虑很多。
  • 您可以将对MyFavFeeds::getLatest()
  • 的调用(而不是代码)放入视图或布局模板,或者更好的是,放入一个ViewHelper,该模板封装了对模型类的调用并呈现小部件。这样,您就不必担心覆盖任何变量或重复。当你的观点不需要标题时,你只是不包括它 关于你的另一个问题:

    在我看来,我称之为 运行我的身份验证系统,然后 请求用户的登录状态。 然后我用这个布尔值来决定 是否显示某些元素 在视图中,以及放置位置 其他的

    身份验证是在调用任何控制器操作之前,您希望在应用程序流的早期执行的操作。因此,您不应该在视图中运行(整个)身份验证系统。实际的身份验证不是与视图相关的逻辑。另一方面,仅在身份验证后请求用户状态是可以的。例如,如果您希望呈现一个显示用户名并提供登录/注销按钮的小部件,可以执行以下操作

    <?php //UserHelper
    class UserMenuHelper
    {
        public function getUserMenu()
        {
            $link = '<a href="/user/logout">Logout</a>';
            if(MyAuth::userHasIdentity()) {
               $link = sprintf('<a href="/user/logout">Logout %s</a>',
                                MyAuth::getUsername());
            }
            return $link;
        }
    }
    

    但是我认为使用MVC的一个主要原因是要在模型和视图之间保持抽象层,这样数据访问代码就不会同时负责呈现视图。通常使用控制器在第2层之间进行调解。这一抽象层确实是主要原因之一,它叫控制器。基本上,将控制器视为用户调用的入口点。它只是从模型中收集数据(或在那里发送数据)并呈现一些东西。这是正确的,但是,您并没有显示模型中的任何内容,您只是决定需要显示哪个视图。如果您要从模型中写入输出缓冲区,那么这将破坏抽象。您甚至不确定模型中显示的内容。模型实际上不知道关于控制器或任何视图的任何信息。理论上:-)这就是我在想的