PHP前端控制器与MVC



我正试图通过前端控制器设计深入研究MVC。

我想通过使用一行来调用我的整个应用程序,例如在index.php:中

require_once(myclass.php);
$output = new myClass();

我很想去掉require_one行,但我不明白如果不包括它,我怎么能加载我的类?

无论如何,我的主要问题是如何使用一个前端类加载我的各种控制器、模型和视图等。到目前为止,我已经想出了:

class myClass
{
private $name;
public $root = $_SERVER['DOCUMENT_ROOT'];
private $route = array("Controller" => "", "Model" => "", "View" => "", "Paremeters" => "");
function __construct() 
{   $uri = explode("/",$_SERVER['REQUEST_URI']);
if(isset($uri[2])) {$this->route['Controller'] = $uri[2];}
if(isset($uri[3])) {$this->route['Model'] = $uri[3];}
if(isset($uri[4])) {$this->route['View'] = $uri[4];}
if(isset($this->route['Controller'])) 
{
include($this->root."/".$this->route['Controller'].".php");
}
}
}

但这似乎有点令人费解,有些过头了。此外,一旦我在__construct中包含了新类,我应该如何加载它?

我很抱歉缺乏知识,我已经在谷歌上搜索了很多次了,我不断地找到同样的页面,这些页面似乎并没有扩大我对这件事的了解。

如果您的URL肯定是http://domain.com/[controller]/[action]/参数,那么您的前控制器可能看起来像这样:

<?php
class Application
{
public function __construct()
{
$this->setupAutoloader();
$this->route();
}
private function setupAutoloader()
{
// do your autoloading here
}
private function route()
{
$request = explode('/', trim($_SERVER['REQUEST_URI'], '/'));
$controller = isset($request[0]) ? ucwords(array_shift($request)) . 'Controller' : 'HomeController';
$action = isset($request[0]) ? array_shift($request) : 'index';
$parameters = $request;
$response = call_user_func_array(array($controller, $action), $parameters);
}
}

从这里,您可以添加您的自动加载器实现,对响应执行任何您想要的操作,并从index.php中调用它,如下所示:

<?php
require 'path/to/Application.php';
$application = new Application();

不幸的是,如果第一个文件存储在文件系统的其他地方,你总是必须包含它,但如上所述,你可以从这里自动加载其他类,如库、控制器、模型等。

我很惊讶,在之前的两个冗长而翔实的答案中,没有人愿意以最简单的方式回答你的问题。

您需要__autoload()函数。您仍然需要在代码中的某个地方定义它,但它可以简单地添加到全局头文件中,然后不必为每个类定义显式地编写include。

/* auto load model classes */
function __autoload($class_name) {
$filename = 'class.' . strtolower($class_name) . '.php';
$file = __SITE_PATH . '/_model/' . $filename;
if( file_exists($file) == false ) {
return false;
}
require($file);
}

为了在不手动包含类的情况下加载类,您应该查看spl_autoload_register,它使您能够在应用程序需要时自动加载类。

至于另一个问题,好吧,这完全取决于你的设计。如果你想加载通用的"控制器"one_answers"操作",你应该创建一个可路由的文件夹(这意味着只有控制器才能驻留的文件夹),放置所有控制器类,然后创建一个可以路由的操作空间(控制器类内的一组可路由方法,通常是通过定义操作方法以action_为前缀的约定)。当你完成后,只需创建这样的控制器:

class Blog {
public function action_posts() { ... };
}

并对其进行管理,使得URL CCD_。(它只需要你已经证明擅长的URI操作)。(请注意,自动加载器应该自己处理实际类文件的包含,而不需要加载所有控制器类)。一旦你有了控制器的名称和操作,你只需要在上做一些事情

if (class_exists($controller)) {
$app = new $controller;
if (method_exists($app, $action)) {
$app->$action(); // also take a look at call_user_func and call_user_func_array
}
}

你也可以允许参数,但这将是相当困难的,为了允许这种结果:

class Blog {
public function action_post($id) { ... };
}

并且例如由CCD_ 4调用。

在处理URI时,还要记住,您可能有错误的输入,并且应该处理它们,但如果您已经创建了正确的路由空间,那么您已经完成了一半。

最后,如果你想获得灵感或其他任何东西,只需看看CodeIgniter(这是最容易学习的框架之一)或任何其他框架。

希望它能有所帮助。

相关内容

  • 没有找到相关文章

最新更新