2012-01-12 49 views
1

介绍如何实现MVC在PHP

,因为在假期前的模型 - 视图 - 控制器方法一直在我的脑海,我真的需要我的web应用程序中得到它归结为一个发球,在创建PHP。

到目前为止,我了解一般的MVC概念以及为什么这样做,但我需要一些帮助。这是一个大学项目,当我提出关于MVC的问题时,我的项目顾问不是很有帮助。

的应用

这是一个任务管理系统,或待办事项列表。目标是一个非常简单的界面,用户可以使用他们的Facebook帐户登录,创建,修改或删除任务,以及使用Javascript和PHP创建的注销。

的事实

我有一个静态的PHP页面here包含像 “top_div” 和 “main_div” 的div。目标是包含“controller.php”(我还没有创建这个)以在视图和模型之间提供服务。

重要提示:在页面上一切使用jQuery的,这样用户将永远不会看到一个页面刷新。我有一个函数可以淡出div中的内容,抓取新需要的内容,将它放在div中(隐藏,因为div已淡出),然后再次淡入div。

目的是让控制器从模型请求,然后发回(例如)Facebook登录按钮到视图。此Facebook登录按钮是HTML。会有其他内容,如文本和HTML的内容,如果用户已经登录“欢迎”将被发送到#main_div 使用PHP,jQuery和cURL

我使用的对象,所以从我理解我将需要实例化一个对象来做数据库连接和查询。我在哪里实例化对象?我读过它们应该在控制器中创建,但是从我读过的其他所有控制器都是简单的,告诉模型视图只是作为中介而行事。我对模型实例化对象的印象(对我来说更有意义)。

1)所以,请向我解释如何在模型中实例化对象是不正确的。如果情况并非如此,那么就我对MVC方法的理解而言,这将非常棒。

可以说用户已经登录。我将在视图(index.php)上显示他们的名字和他们的Facebook图片。如果您在上面的链接上访问该网站,则可能会在右侧看到一张小图片,显示该图片。针对用户的PHP中图片的代码看起来是这样的:

<img src="https://graph.facebook.com/'.$fbid.'/picture" width="79" height="64" align="center" style="opacity:0.8;">';

2)作为该HTML将被传递到该视图被显示成使用上述jQuery函数一个DIV,是它好为我控制器有这种信息出去?我的控制器可以具有沿(pseduo代码)线的东西:

if(user is logged in(from checking via model)) then { send to #main_div the html above };

我可以想出一大堆。随着这种方式更多的问题,但请有人可以帮助我更加了解我在做什么?

+3

这里您会收到广泛的回复。事情是,MVC是一个相当简单的模式,可以实现一百万种不同的方式。 – dqhendricks 2012-01-12 22:35:46

回答

1

1)那么,请向我解释在模型中实例化 对象的方式是不正确的。

这完全没有错。目标是瘦控制器和胖模型,但是,我在我的控制器中创建对象,并让模型/服务完成繁重工作。注意:最好在自举的其他位置创建对象,并使用dependency injection将这些对象提供给控制器。话虽如此,我的很多对象创建都是在控制器中根据需要进行的。

2)作为该HTML将被传递到该视图被显示成使用上述jQuery函数一个DIV ,是它好为我 控制器具有这种信息出去?

是的。控制器会将数据从模型传递到视图。

MVC框架的建议

除非你只是想,或有,不推出自己的MVC。选择一个框架,做一点研究,然后获胜。

+1

啊我记得写这个,没有线索,现在我已经写了我自己的,了解MVC好多了,使用Symfony和真正的自动布线依赖注入容器,如[Auryn](https:// github。 COM/rdlowrey/Auryn)。我现在有你暗示的胜利,欢呼! :) – Jimbo 2013-07-02 08:59:45

+0

不喜欢你关于胖模型的陈述。模型根本不应该胖,它们只是表示数据,没有别的...... – Pinoniq 2014-05-10 16:40:54

+0

完全取决于模型的含义,这通常是一个滑溜溜的词。模型定义为数据表示时,我同意100%。然而,使用Model包含应用程序的业务逻辑并不合适。创建精简控制器和胖模型的警告只是意味着应该将业务逻辑放在控制器之外。当我说“模型/服务”应该做“繁重”时,我试图表达这一点。 – 2014-05-10 20:55:43

0

首先,你的静态php页面不包括控制器。反过来,你的控制器包含你的静态php页面(视图)。

一个吻,添加一些

<!--parsableTags!--> 

到您的视图和负载对应机种填补这些标签。让控制器将结果反馈给呼叫浏览器。

ADDITION:

控制器中的数据库逻辑与否?这里没有绝对的真理,你的应用程序可能主要针对LDAP,那么为什么要加载一个数据库服务?你想要的可能是一个配置,由控制器在启动时读取以加载初始组件。

一些人认为只有视图才能生成html,这是一个很好的原则,但可能会让你在1点钟生气。

但最后有很多不同的方法来做到这一点。

1

一般最所有的代码应该基于对象的。 “控制器”部分将根据用户请求进行操作。因此,让我们说一个人请求“www.you.com/?login”,控制器应该获得“登录”的请求。控制器(有时被称为路由器)将实例化适当的“Model”对象来处理登录。在这种情况下,它可能只是创建模型(登录)对象,没有数据告诉控制器显示“view-login”。然后控制器转到视图对象代码并为其提供适当的视图来显示,并且视图对象以登录形式返回呈现的HTML页面。

一旦用户提交了他的信用,请求将是“POST:action = login,username = blah,password = 12345”。然后控制器会看到它需要调用登录对象并将参数username/password传递给登录“model”。登录模型逻辑会处理参数,然后发送给控制器显示“view-login,success”。然后控制器会告诉视图对象使用附加参数显示该视图,并且视图对象将呈现页面并输出它。

在您的应用编码过程中,这可以继续扩展。使用自动加载功能,您甚至可以让您的控制器扫描模型/视图的目录,并动态实例化请求的对象,或者在默认对象不存在的情况下对默认对象进行回退。这样,每次添加模型/视图逻辑时,都不需要修改控制器。另一个好处是您的应用程序只有一个入口点,例如所有的URL都将是www.you.com/?login或www.you.com/?task=2 & action =删除...等等等等。在写作你自己的作品时,要多多阅读,不要感到沮丧。在您真正了解您希望MVC的行为方式之前,您可能会多次放弃您的工作。

良好的阅读: http://oreilly.com/php/archive/mvc-intro.html

0

我会建议在寻找存在于PHP中使用MVC,使容易(至少作为一个例子来回绕其他人是如何做的你的头)的一些其他库。浮现在脑海中有几个是:

  • Zend框架
  • CakePHP的

...然后当你准备好真正提高你的代码;)看看这些Ruby库:

0

控制器类应处理所有到服务器的请求,然后基于请求对所需的任何模型对象执行任何操作,然后将所需的任何数据传递给视图对象,然后呈现该页面。

有一百万种方法可以设置它。基本的想法是保持你的业务逻辑与视图呈现(HTML)分开。

一些提示:

在很多的意见,你不应该让模型加载其他模型本身。相反,你会使用依赖注入模式来减少强耦合。这基本上意味着通过构造函数或方法参数插入任何必需的对象。

很多人会使用所谓的依赖注入容器。这通常是一个具有一个公共方法的类,用于实例化除Controller类以外的所有其他类。在PHP 5.3中,您可以使用闭包来帮助延迟加载从di容器请求的任何类。如果对象是一个将被共享的对象(如单例),则dic类也可以存储对象以供以后重用,但是您始终会以与dic相同的方式请求该类。这一点的关键在于,如果您需要改变类的实例化方式,或者想要将其与扩展类或使用相同接口的其他类交换,则此类修改都可以在一个地方在你的代码而不是很多。它也有助于保持你的控制器“轻”。

0

分离问题。

把你的逻辑呈现在您的PHP视图文件的HTML。

把JavaScript和CSS在自己的文件,并引用它们的外部

把你的车。 DAO(数据访问对象)中的逻辑 - 只有它们与db,而不是VIEW文件交谈。

创建你的控制器为一个普通的php页面,如index.php或controller.php,如果你喜欢。每个请求都通过索引或控制器文件。控制器文件将包含对javascript和css文件的外部引用。

每次回到控制器的回调函数都会包含一个参数和变量,用于确定将控制权交给哪里。控制器可能会有一个swich-case或if-else结构来处理特定的请求。像这样:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
<script src="assets/ajax.js" type="text/javascript"></script> 

<link rel="stylesheet" type="text/css" href="assets/adminApp.css" media="screen" /> 
<link rel="stylesheet" href="assets/print.css" type="text/css" media="print" /> 

<?php 
    require_once('../../config.php'); 
    require_once('../connect_db.php'); 
    require_once('../custom_boces_dao.php'); 
    require_once('../custom_boces_gateway.php'); 

    if(isset($_REQUEST['action'])){ 
    $action = $_REQUEST['action']; 
    }else{ 
    $action = "viewUserAttributes"; 
    } 

echo "<div id='leftNav'>"; 
    require_once('views/global_navigation.php'); 
echo "</div>"; 

echo "<div id='mainArea'>"; 

    switch ($action) { 

     case 'home': 
     echo "something to say"; 
     break; 

     case 'viewCourseAttributes': 
     require_once('views/course/frmCourses.php'); 
     break; 

     case 'editCourseAttributes': 
     require_once('views/course/frmCourses.php'); 
     require_once('views/course/frmCourseAttributes.php'); 

     break; 
     . 
     . 
     . 
}  

echo "</div>"; 

?>   
0

让我们从基础开始。要首先构建一个体面的MVC框架,您需要一个引导程序。一个程序,它将确定你的应用程序需要做什么。之后它需要将数据传递给适当的函数(类)。一个好的方法是创建一些路由表,例如正则表达式和一些默认指向表达式不匹配的路由表。例如它可以是:/ module/controller/action/params。 bootstrap应该负责所有的初始化,读取配置,确定要传递到哪里。为了简化编码,您可以使用命名空间创建一个结构。例如,您需要在一个地方使用控制器,在其他地方使用模型和视图。由于PHP < 5.3不支持命名空间,因此可以使用目录结构命名空间轻松处理它。这意味着一个目录是你的命名空间,其中的所有文件都遵循某种模式。这样你就可以轻松地自动加载类。在你将它们分离到适当的命名空间之后。你的库类可以到库/,你的帮助类到助手/等等。所有控制你的实际应用程序逻辑的控制器都可以进入一个模块命名空间。例如前端/和后端/。他们都需要扩展你的基本控制器类(从库/名字空间加载),它将处理视图初始化。

+0

另一种方法是让Apache处理路由并让控制器“引导”自己。然而,许多“框架”通过单个前端控制器执行每个请求,该前端控制器根据请求路由到适当的控制器。 – dqhendricks 2012-01-12 22:32:39