PHP MVC,谁拥有URL?
我正在使用MVC技术实现一个PHP应用程序。加载PHP MVC,谁拥有URL?,php,oop,model-view-controller,architecture,model,Php,Oop,Model View Controller,Architecture,Model,我正在使用MVC技术实现一个PHP应用程序。加载http://site/photos/25?options其中重写为http://site/index.php?page=photos&id=25&options: index.php->实例化并调用PhotoController对象 PhotoController实例化PhotoView并将正确的Photo(模型)加载到其中 PhotoController调用PhotoView->render(),以及页眉/页脚视图 PhotoView可以访问
http://site/photos/25?options
其中重写为http://site/index.php?page=photos&id=25&options
:
->实例化并调用index.php
对象PhotoController
实例化PhotoController
并将正确的PhotoView
(模型)加载到其中Photo
调用PhotoController
,以及页眉/页脚视图PhotoView->render()
可以访问PhotoView
模型及其所需的其他模型数据Photo
PhotoView
将输出HTML并希望超链接到不同的页面。当该视图生成超链接时,我不知道哪一层应该拥有URL。我看到的选项概述如下。请帮我选择正确的方法
模型层拥有URL 模型有一个
getURL()
方法
优点:
- 基本
类可以包含开放图属性视图
可以这样做:PhotoView
$folderHref=$photo->getFolder()->url
- 有些控制器没有一个对应的模型,例如
,LoginController
,如何获取这些控制器的URLAdminController
控制器拥有URL 控制器具有
url
和title
属性。要创建链接,演示控制器将创建目标控制器并传递到视图。视图从传递的对象访问url
和title
优点:
- 每个URL都直接映射到一个控制器(在
中),因此相反的看起来是干净的index.php
- 如果视图需要其他视图的URL,则需要以下一种丑陋的攻击:
- 查询不相关的控制器
$folderHref=Controllers\FolderController::urlForFolder($photo->getFolder())
- 视图对其控制器了解太多
$folderHref=$photo->getFolder()->getControllerAndSetURL()->getURL()
- 视图与其控制器之间的过度通信
和$folderHref=$this->delegate->getURLForFolder($photo->getFolder())
具有许多方法的$adminHref=$this->delegate->getURLForAdminHref()
委托
- 查询不相关的控制器
每个人都拥有URL 基类
OpenGraphObject
是控制器
和模型
的父类,并且有一个方法getURL()
控制器
和模型
仅在无参数运行时实现此功能。(例如,PhotoController
返回NULL,因为URL取决于将显示哪个Photo
)
优点:
- 以上所有优势
- 混乱
- 吊销我的编程许可证
/**
* Responsible for processing and rendering user output
*/
interface View {
public function render();
}
/**
* Used just to further formalize the messages between Photo and View
*/
interface PhotoView extends View {
public function setPhotoData($id, $title, $link);
}
/**
* Among other things knows how to generate URLs to routes
*/
interface Router {
/**
* Returns the URL to route based on route name
* @param string $routeName
* @param array $params
*/
public function urlTo($routeName, $params = null);
}
<a href="<?= $userLogin['href'] ?>"><?= $userLogin['label'] ?></a>
<a href="<?= $userRegister['href'] ?>"><?= $userRegister['label'] ?></a>
<div>
<img src="<?= $photo['src'] ?>" title="<?= $photo['title'] ?>" />
<a href="<?= $photoLink['href'] ?>"><?= $photoLink['label'] ?></a>
</div>
我不打算实现每个类,有很多现成的解决方案可以使用,例如模板引擎和路由器
基于id显示图像的示例控制器可以是:
class PhotoController {
public function displayAction($photoId) {
$photo = Photo::findById($photoId);
$templateFile = $this->pathTo('photo-template.php');
//can be a singleton for example, it holds all the routes for the application
//and knows how to render them based on the name and parameters
$router = AppRouter::instance();
return $photo->render(new ConcretePhotoView($templateFile, $router));
}
}
在此示例中,Photo需要能够从DB中提取自身,然后将自身渲染到PhotoView:
class Photo {
private $id;
private $title;
private $sourceLink;
//other methods...
public function render(PhotoView $view) {
$view->setPhotoData($this->id, $this->title, $this->sourceLink);
return $view->render();
}
}
假设HTML模板photo template.php
如下所示:
/**
* Responsible for processing and rendering user output
*/
interface View {
public function render();
}
/**
* Used just to further formalize the messages between Photo and View
*/
interface PhotoView extends View {
public function setPhotoData($id, $title, $link);
}
/**
* Among other things knows how to generate URLs to routes
*/
interface Router {
/**
* Returns the URL to route based on route name
* @param string $routeName
* @param array $params
*/
public function urlTo($routeName, $params = null);
}
<a href="<?= $userLogin['href'] ?>"><?= $userLogin['label'] ?></a>
<a href="<?= $userRegister['href'] ?>"><?= $userRegister['label'] ?></a>
<div>
<img src="<?= $photo['src'] ?>" title="<?= $photo['title'] ?>" />
<a href="<?= $photoLink['href'] ?>"><?= $photoLink['label'] ?></a>
</div>
最后回答“谁拥有URL?”——路由器。这些知识封装在那里,并且特定于应用程序配置。其他对象使用它来生成链接。您看过codeigniter或其他mvc框架吗?所有这些工作都是为您完成的,尽管这非常有趣。我不确定开放图的属性是什么。您能否提供一个具体的示例,说明视图呈现的预期html以及您的应用程序涉及哪些其他对象来生成该html?OpenGraphObject只是一个具有开放图形规范属性的类,例如$title、$url、$image、$type刚研究了CodeIgniter方法,看起来它们使用了硬编码和实用程序类,例如,
echo base_url(“blog/post/123”)代码>。当然这里的blog
和post
都是硬编码的。这可能不是个坏主意,但会破坏MVC IMHO。有关“MVC”的有用信息-我建议您阅读这些信息。您的控制器似乎在做一些不应该负责的事情(例如使用操作活动记录、选择模板和渲染视图)。而且很明显使用了单例反模式。但是让我们忽略这一切。。。因为我真正不明白的是:在现实世界中,你在哪里需要基于路由器为模板生成URL?你什么时候处理过在同一模板的不同上下文中完全改变的URL(不仅仅是ID部分)?我的理解是,当一个对象告诉另一个对象为它做工作时,它不是在做实际的工作。控制器将渲染委托给视图,并将DB回迁委托给其他对象。它不做实际工作。我想知道视图的路径可能会被移动到实际视图,这样控制器知道的就更少了。至于使用Singleton,在我看来,每个应用程序都有一个路由器是合理的。你能不能详细说明一下URL和模板备注,我不明白。感谢comment.IMO,如果控制器中实际包含HTML标记和SQL查询,那么控制器将执行HTML呈现和Db获取。不,事实上情况更糟,因为您获取一个活动记录实例,向其传递一个模板,然后控制器呈现AR实例。这是为什么?这张照片是封装的