3

我正在尝试学习 MVC,并且我想在 URL 为 www.example.com/store 并且另一个购物车页面的 URL 为 www.example.com/store/cart 时显示商店页面。这两种方法都在一个类中:

class store extends controller {
    function __construct() {
        parent::__construct ();
    }

    function Store() { //this should display the store page
        $this->view->render ( "store" );
    }

    function cart() { //this should display the cart page
        $this->view->render ( "store", "cart.php" );
    }
}

该方法$this->view->render()包括带有 html 代码的页面。如何根据 url 决定执行哪种方法?

4

3 回答 3

10

我可以看到您正在尝试编写自己的 MVC,因此我将尝试解释您在执行此操作时应该注意的事项。

编写 MVC 时要做的第一件事是利用前端控制器模式。这意味着每个 HTTP 请求都将通过一个文件 index.php。这将帮助您在一个文件中配置您的应用程序。你可以通过总是打开你的让说来做到这一点:

www.example.com/index.php/controller/method/param1/param2

或者您可以强制用户使用 .htaccess 文件浏览 index.php。如需参考检查其他框架,如 Codeigniter 和 CakePHP,请查看它们如何使用 .htaccess 文件。

当您在前端控制器文件中时,您应该考虑将 HTTP 请求路由到适当的控制器/方法。确实有很多方法可以实现这一目标,而这取决于您找出实现这一目标的最佳方法。

无论如何,您需要 Router 类来分析您的 URL,并从 URL 中提取您需要的控制器/方法/参数。然后,当您知道需要调用什么控制器/方法时,您需要将实例化控制器的 Dispatcher 类,并调用您需要的方法。您还应该考虑要传递给您的方法的参数,以便您可以在那里使用它们。

解决这个问题的最简单方法是使用查询字符串。

所以假设你有这样的 URL:

http://localhost/test/index.php?controller=home&method=welcome

您可以轻松获取控制器和方法名称。

现在您可以执行以下操作:

// Get controller and method names
$controller = $_GET['controller'];
$method = $_GET['method'];

// Instantiate controller object
$app = new $controller();

// Call method on you controller object
call_user_func_array(array($app, $method));

这就像你可以做的最简单的事情只是为了玩耍。一旦你掌握了这一点,编写你的路由器类,使其看起来像这样:

http://localhost/test/index.php/controller/method/param1/param2

无论如何,您需要这些课程:

前端控制器,因此每个请求都通过一个文件,这是您引导应用程序、注册类自动加载、配置所有内容等的地方……这不是一个类,而是一个包含启动所有内容的程序代码的文件。

路由器将分析 URL 并将您想要传递给调用方法的控制器、方法和参数返回给您。

Dispatcher将实例化 Controller 并调用 Method,将 Params 传递给您的 Method。

然后所有的控制权都交给你系统的用户,然后你在你的控制器/方法中施展你的魔法。

在调度请求时,您也可以使用它:

call_user_func_array(array($app, $method), $params);

这样,您将 $params 传递给 $method,因此您可以在方法中使用 $params。

另外,查看反射类,这可以帮助您分析要调用的方法是否存在,如果不存在,则应调用 HTTP 404 等...

您的问题没有简单的答案,但我希望这会有所帮助,享受构建系统的乐趣并不断改进,直到您得到完美:)

于 2013-04-08T12:33:55.383 回答
2

您需要有一个单独的路由器类来向控制器发送路由请求。我建议查看/复制Symfony 的 Router

于 2013-04-08T11:39:17.517 回答
1

我曾经为家庭酿造方法做过类似的事情。使用 .htaccess (apache) / Web.config (iis) 将所有请求重定向到以下脚本。

// include callable controllers here
$partsA = explode("?", $_SERVER['REQUEST_URI']); // split querystring
$partsB = explode("/", $partsA[0]); // get url parts
if (count($partsB) < 2)
    die("missing controller in url");
elseif (count($partsB) < 3)
    die("missing action in url");
$className = $partsB[1];
$methodName = $partsB[2];
if (class_exists($className))
    if (!is_subclass_of($className, "controller"))
        die(htmlspecialchars("Class $className doesn't extend controller")); // prevents use of unauthorized classes
    else
        $controller = new $className();
else
    die(htmlspecialchars("Class $className doesn't exist"));

if (!method_exists($controller, $methodName))
    die(htmlspecialchars("Method $methodName doesn't exist"));
else
    $controller->$methodName();
于 2013-04-08T12:17:55.737 回答