【问题标题】:PHP, understanding MVC and CodeigniterPHP,了解 MVC 和 Codeigniter
【发布时间】:2012-05-21 07:01:49
【问题描述】:

我正在尝试了解 MVC,并学习 CI 框架。我有一些关于 MVC 的问题和一些关于 CI 的基本问题。

1)当我从教程中阅读时,视图是应用程序的可视化部分,我的问题是:例如,有一个“登录”按钮,但如果用户已经登录,按钮将是“注销”。登录检查在哪里?在控制器上还是在视图上?我的意思是

   //this is view//

     <?php if($_SESSION('logged') == true):?>
     <a href="logout">Logout</a>
     <?php else: ?>
     <a href="login">login</a>        
     <?php endif; ?>

  //this is controller//

 if($_SESSION('logged') == true)
 $buttonVal = 'logout';
 else
 $buttonVal = 'login';

 //and we pass these value to view like
 $this->view->load('header',$someData);

 //this time view is like
 <a href="<?=$somedata['buttonVal']?>"><?=$somedata['buttonVal']?></a>

我只是写这些代码作为示例,我知道它们不会工作,它们是虚构的代码,但我想你明白我的意思。登录检查应该在控制器上还是在视图上?

2) 模型应该只包含有关数据的代码并将它们返回给控制器吗?例如有一个数学,我们从数据库中获取 2 个值并将它们相乘并显示它们。模型会成倍增长还是控制器会成倍增长?

在这里,我们使用模型加载数据并在控制器上进行数学运算: //模型

   $db->query(....);
   $vars=$db->fetchAll();

   return $vars;

   //controller
   $multi = $vars[0] * $vars[1];
   $this-load->view('bla.php',$mutli);

这里我们使用模型加载数据并对模型进行数学运算,控制器只是将数据从模型传递到视图:

   //model

   $db->query(....);
   $vars=$db->fetchAll();
   $multi = $vars[0] * $vars[1];
   return $multi;

   //controller
   $multi = $this->model->multiply();
   $this-load->view('bla.php',$mutli);

我的意思是,模型应该只做数据库工作并将数据传递给控制器​​,控制器做剩下的工作并将视图发送到渲染?或者模型确实有效,控制器获取它们并将它们发送到视图?

3)这是关于codeigniter的,我有一个必须在每个页面中的标题,但它有javascripts,css取决于我正在使用的页面

        <?php foreach ($styles as $style): ?>
        <link id="stil" href="<?= base_url() ?>/css/<?= $style ?>.css" rel="stylesheet" type="text/css" />
        <?php endforeach; ?>

这将在每个页面上,所以在我拥有的每个控制器中

$data['styles'] = array('css1','css2');
$this->load->view('header', $headers);

我正在考虑做一个主控制器,在里面写这个,我所有的其他控制器都会扩展这个,我在 CI wiki 上看到了 MY_Controller,这个 MY_Controller 和我正在做的一样吗?有没有其他方法可以做到这一点?

对于糟糕的英语和虚拟问题,我们深表歉意。感谢您的回答。

【问题讨论】:

  • 由于您使用的是 CodeIgniter,因此您不必担心理解 MVC,因为您将不得不在稍后阶段消除他们对它的所有误解。做现在有效的事。
  • 看看这个:Detailed Overview Of MVC
  • @Gordon 你能详细说明这些误解是什么吗?
  • @Repox 他们的用户指南声称“模型是 PHP 类,旨在处理数据库中的信息”,然后继续显示除了执行 CRUD 之外没有其他目的的类,给人的印象是模型 == 数据库,这是错误的。此外,他们所谓的 ActiveRecord 实际上是一个非常简单的 QueryBuilder。如果您愿意深入了解他们的代码,我相信还有更多内容可以找到。
  • @Repox 如果他们明确指出模型是由附加层组成的层,例如服务层、域模型、持久层等,并且确实是您的应用程序的核心,那么我不会介意CRUD 示例,但没有类似的东西,如果您查看 SO 上的问题,您会发现 CI 用户认为 Model 是一个仅执行 CRUD 的类。至于AR,它甚至不是修改版。 AR 是一个添加了业务逻辑的行对象。他们的修改版本根本不是那样的。我同意有很多糟糕的框架,但 CI 是最糟糕的框架之一。

标签: php model-view-controller codeigniter model


【解决方案1】:

这绝对是视图逻辑,在我看来是正确的做法:

 <?php if($logged_in):?>
 <a href="logout">Logout</a>
 <?php else: ?>
 <a href="login">login</a>        
 <?php endif; ?>

$logged_in 的值可能会从对库方法的调用中检索到:

<?php if ($this->auth->logged_in()): ?>

身份验证是您希望全局访问的内容之一,因此您可能出于不同原因在控制器或视图中调用$this-&gt;auth-&gt;logged_in()(但可能不在模型中)。

在我拥有的每个控制器中

$data['styles'] = array('css1','css2');
$this-&gt;load-&gt;view('header', $headers);

是的,您可以使用MY_Controller 扩展控制器类,但最好将其保留在视图/表示层中。我通常创建一个主模板:

<html>
<head><!-- load assets --></head>
<body id="my_page">
  <header />
  <?php $this->load->view($view); ?>
  <footer />
</body>
</html>

并编写一个用于加载模板的小包装类:

class Template {
  function load($view_file, $data) {
      $CI = &get_instance();
      $view = $CI->load->view($view_file, $data, TRUE);
      $CI->load->view('master', array('view' => $view));
  }
}

在控制器中的使用:

$this->template->load('my_view', $some_data);

这样可以避免重复加载页眉/页脚。在我看来,展示逻辑,如加载哪个 CSS 文件或页面标题应该尽可能属于视图。

就模型而言,您希望它们是可重用的 - 所以让它们做您需要的事情,并使其与数据操作(通常只是您的数据库)严格相关。让您的控制器决定如何处理数据。

与 MVC 无关,但通常您希望编写尽可能少的代码。冗余表明您可能会找到更好的解决方案。这些是广泛的提示(就像您的问题一样),但希望对您有所帮助。

【讨论】:

    【解决方案2】:

    1) 视图逻辑应该很简单,如果需要的话,主要是 if-then 语句。在您的示例中,任何一种情况都可以,但使用视图中的逻辑。但是,如果您正在检查登录并在未登录时重定向,那么这将发生在控制器(或库)中。

    2) 将 Codeigniter 模型视为访问数据库功能的方式 - 创建、检索、更新、删除。对于 Codeigniter 模型,我的(松散的)经验法则是返回更新、删除或插入查询的结果或提取查询的结果集。然后可以在控制器中进行任何适用的数学运算。如果这是每次都会发生的数学运算,请考虑将其添加到库函数中。见下文...

    3) 扩展控制器是实现此目的的正确和最佳方式。

    *) 不要在你的盘子里添加更多,但也一定要了解Codeigniter Libraries。例如,在您的控制器中,您可以加载您的库。然后你从你的控制器调用你的库函数。库函数调用一个模型来检索您的数据库结果。然后库函数对该函数执行数学运算并将结果返回给控制器。控制器只剩下很少的代码,但由于库和模型而完成了很多工作。

    【讨论】:

    • -1 表示“将模型视为数据库访问功能”。模型不仅仅是数据库。
    • 来自 Codeigniter 用户指南“模型是 PHP 类,旨在处理数据库中的信息。”
    • 模型不仅仅是 CRUD 函数。
    • Codeigniter 用户指南不应该是您从中获取概念的东西。只是说。
    • @ChristopherIckes 他们错了。他们还声称他们的 QueryBuilder 是 ActiveRecord,但事实并非如此。
    【解决方案3】:

    用户登录检查应该在控制器中。 这应该是需要在构造函数中调用的第一个函数。

    Below i have given the sample code which redirects the user to the login page if he is not logged in, hope this would give you some idea,
    
    <?php
    
    class Summary extends Controller {
    
        function Summary() {
            parent::Controller();
            $this->is_logged_in();
        }
    
        function is_logged_in() {
            $logged_in = $this->session->userdata('logged_in');
            if (!isset($logged_in) || $logged_in != true) {
                $url = base_url() . 'index.php';
                redirect($url);
                exit();
            }
        }
    
    ?>
    

    通过检查视图中的会话变量并做出相应的决定,可以在视图中实现按钮更改。

    请看这个link

    【讨论】:

    • 你说The user lo-gin check should be in the controller.,然后最终写了视图中的逻辑......
    猜你喜欢
    • 1970-01-01
    • 2013-05-11
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    • 2015-11-05
    相关资源
    最近更新 更多