【问题标题】:How do you pass values between PHP pages for MVC?如何在 MVC 的 PHP 页面之间传递值?
【发布时间】:2010-09-30 17:45:25
【问题描述】:

PHP 程序如何在模型、视图和控制器页面之间传递值?例如,如果控制器有一个数组,它如何将它传递给视图?

编辑:

感谢您的回答。我看到其中有几个声明组件在同一个页面中,但是当我查看 CodeIgniter 之类的东西时,我看到了模型、视图和控制器的三个单独的 PHP 页面。

【问题讨论】:

    标签: php model-view-controller


    【解决方案1】:

    通常您的控制器将创建一个视图对象,并在创建该视图对象时传递信息。

    <?php
    
    class Controller {
        public function __construct() {
            $arr = array("a","b","c");
    
            $myView = new View($arr);
        }
    }
    
    class View {
    
        private $content;
    
        public function __construct($content) {
            $this->content = $content;
            include_once('myPage.inc.html');
        }
    }
    
    
    ?>
    

    【讨论】:

    • 当您在上面执行“include_once”并运行上面的 php 时,我是否正确地在上面的当前 php 页面中包含 .html?为什么不把所有内容都放在一个页面上?
    • PHP 不像 c++ 或 c#,因为您不包含或使用名称空间(PHP 5.3 实际上有名称空间)当您使用 include_once() 时,您实际上将该脚本附加到页面。拆分脚本的主要原因是为了编程逻辑。
    【解决方案2】:

    CodeIgniter 与大多数 PHP MVC 框架一样,带有一个视图“引擎”。换句话说,框架中有一个类负责将数据从控制器加载和传输到视图。

    特定于 CodeIgniter,这些调用如下所示:

    $data = array(
               'title' => 'My Title',
               'heading' => 'My Heading',
               'message' => 'My Message'
          );
    
    $this->load->view('blogview', $data);
    

    您的视图将是一个单独的 php 页面,在本例中为 blogview.php。它可能看起来像这样:

    <html>
       <head><title><?= $title ?></title></head>
       <body>
          <h2><?= $heading ?></h2>
          <p><?= $message ?></p>
       </body>
    </html>
    

    负责在控制器和视图之间传输数据的部分是 CodeIgniter 内部的视图引擎(或类)。它从控制器中获取该数组并将其反序列化以用于视图。

    那么为什么是两个单独的文件呢? MVC 范式是这样的,在设计上,您希望您的业务逻辑与您的 UI 分离。如果您对数据库做的不多,则不需要合并 MVC 的模型部分。但是当您想进一步将代码的数据访问部分与业务逻辑(为用户操作数据的东西)分开时,它就在那里。在这种情况下,您有 3 个单独的文件;模型、控制器、视图。

    所以不,这些组件并不都在同一个页面中,尽管它们当然可以。但是通过使用 MVC 构建程序,您可以干净利落地分离应用程序的操作。这样,您可以一次在一个层中工作,而不会影响其他层。例如,当您找出用户无法登录的原因时,您的 CSS 人员可能会让网站看起来很漂亮。

    【讨论】:

    • “负责在控制器和视图之间传输数据的部分是 CodeIgniter 内部的视图引擎(或类)。它从控制器中获取该数组并将其反序列化以用于视图。”但它是如何做到的呢?我将如何从头开始在非常基本的级别上做同样的事情?
    • 使用php函数extract。这会将数组的键转换为单个变量。见php.net/manual/en/function.extract.php
    【解决方案3】:

    我希望约翰尼很久以前就找到了我现在正在寻找的答案,但我可以提供关于如何做到这一点不令人满意的见解!您可以从一个文件(例如收集站点用户输入的数据的“视图”组件)中的一个信息传递到另一个文件(例如检查/验证表单数据并将其发送回表单的“模型”组件用于修订或将其存储在数据库中)。表单值可以通过 POST 或 GET 数组发送,“action”属性确定哪个文件接收数据,例如

    <form action = 'form-exec.php' method = 'POST'>
    ---some set of  possible user inputs goes here
    <input name='submit' type='submit' value='Go'>
    </form>
    

    处理后,您可能希望向表单返回一些数据——例如需要修改的用户输入值或成功消息。您可以将该数据存储在会话变量中,并从“查看”页面上的这些变量中恢复它。那么,如何返回“查看”页面?现在,我在这里是因为我已经看到它使用过并且我自己也使用过它,但是很震惊地读到它,显然,传输是通过一个缓慢的互联网 http 请求进行的——即使传输是到同一个文件中的服务器上的目录!好的,所以返回“视图”组件的不满意方法是几行这样的 PHP 行:

    header("location: theinputform.php");
        exit;
    

    它确实有效,但肯定有更好的方法吗?我看到有人“咆哮”说您应该只使用包含,但我无法理解如何合理地执行日常操作,即返回页面顶部并根据新条件重新创建它。例如,如果我刚刚登录了一个用户,我这次不想显示登录邀请。包含是有条件地向页面添加内容的简单方法,但我没有找到比上述方法更简单地返回顶部的方法。有没有人对此有任何见解或知识?正如 OP 所述,Johnny 和我想做与 MVC 相同的事情,但没有使用任何类型的 MVC 框架。顺便说一句,有几本书和教程简单地使用了上面的“标题”方法。

    好的,编辑:您从表单(即“查看”页面)到使用表单的“操作”属性进行表单处理,如上所述。如果“模型”页面没有输出 html 并且只是“做事”,您可以简单地包含您希望在完成时转到(或返回)的“查看”页面。反正我觉得是!正要试一试……

    【讨论】:

      【解决方案4】:

      我自己也在为这个问题苦苦挣扎。近十年后,我回到了 php 编程。我在将 PHP MVC 框架部署到实验服务器时遇到了几个问题,所以我最终自己构建了一个简单的 MVC 变体。

      在我的简单设计(前端)中,控制器与模型交互以填充有效负载对象并将其传递给视图。每个视图都在一个单独的 PHP 文件中实现,因此控制器使用 include 来“加载”所需的视图。 然后视图可以通过有效负载对象的指定名称 ($dataId) 访问数据。

      class Controller {
              public $model;
              ...
              public function display($viewId,$dataId,$data)
              {
                $url = $this->getViewURL($viewId);
                $this->loadView($url,$dataId,$data);              
              }
      
              public function getViewURL($key)
              {
                  $url = 'view/list_view.php';
      
                  if($key == 'create')
                  {
                      $url = 'view/create_view.php';
                  }
                  else if($key == 'delete')
                  {
                      $url = 'view/delete_view.php';
                  }
      
      
                  return $url;            
              }
      
              public function loadView($url,$variable_name, $data)
              {
                  $$variable_name = $data;
                  include $url;
              }
      }
      

      【讨论】:

      • 谢谢。我最终也滚动了自己的。其他一切都太神奇了。
      【解决方案5】:

      模型、视图和控制器不是单独的页面,而是一页。
      所以,不需要“传递”任何东西

      【讨论】:

      • 为什么它们看起来是单独的页面?例如,CodeIgniter,至少对我来说,显然有三个 php 页面。
      • 与您将任何程序分成多个文件的原因相同。这是为了组织。
      • @simuri 我是说上校说它们不是单独的页面,我说它们是因为我可以看到三个单独的页面,实际上可以编辑三个页面。我不确定你是否明白我的意思。
      • @johnny 这些页面相互包含。这使它们成为一页。
      • @col.所以某处有明确的“包含”或“include_once”?
      【解决方案6】:

      您可以使用smarty 之类的模板引擎将视图与控制器和模型分开。

      并使用例如 smarty 的 assign 方法将变量传递给您的模板。

      【讨论】:

      • @johnny 我不认识自己! ;)
      • 投反对票: 1. Smarty 是有史以来最糟糕的模板引擎之一。 2. Smarty与MVC中的View无关,因为它只是一个模板引擎。
      • 所以你不能用它来将视图与控制器和模型分开?
      • 仅仅因为你对某事有负面看法而对某事投反对票似乎有点奇怪,哈哈
      • @Johhny:视图不是模板。 View 可能(不)使用模板。 @Ascherer:反对票是第二点。 @rahim asgari:Smarty 已被用作“视图工具”,但 Smarty 无法处理任何典型的视图任务,因为它只是一个模板引擎。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-13
      • 1970-01-01
      • 2014-04-22
      • 1970-01-01
      • 2012-09-08
      相关资源
      最近更新 更多