Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/244.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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 MVC,谁拥有URL?_Php_Oop_Model View Controller_Architecture_Model - Fatal编程技术网

PHP MVC,谁拥有URL?

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可以访问

我正在使用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
    可以访问
    Photo
    模型及其所需的其他模型数据
PhotoView
将输出HTML并希望超链接到不同的页面。当该视图生成超链接时,我不知道哪一层应该拥有URL。我看到的选项概述如下。请帮我选择正确的方法


模型层拥有URL

模型有一个
getURL()
方法

优点:

  • 基本
    视图
    类可以包含开放图属性
  • PhotoView
    可以这样做:
    $folderHref=$photo->getFolder()->url
缺点:

  • 有些控制器没有一个对应的模型,例如
    LoginController
    AdminController
    ,如何获取这些控制器的URL

控制器拥有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实例。这是为什么?这张照片是封装的