在Web应用开发中,MVC(Model-View-Controller)模式是一种广泛使用的架构模式。它将应用程序分为三个核心组件:模型(Model),视图(View)和控制器(Controller),以此来分离应用程序的不同方面,提高代码的可维护性和可扩展性。PHP社区提供了大量的开源MVC框架,这些框架极大地简化了开发过程。然而,对于小型项目,倾向于不使用任何MVC框架,以保持代码库的简洁。在这种情况下,通常会开发一个轻量级的MVC框架,以加快请求分发的速度。本文将介绍一个可以作为启动项目的轻量级MVC框架,以及其目录结构和使用方法。
框架的目录结构如下:
使用框架的请求执行始于index.php
文件,它创建了System\Application
的一个新实例。以下是如何使用这个框架的示例代码:
require 'System/Application.php';
try{
$app = new \System\Application(dirname(__FILE__));
$app->addRoute(
'custom route',
new \System\Routing\DynamicRoute(
'/^article/',
'Article',
'view'
)
);
$app->run();
}catch(Exception $e){
\System\Debug::report($e);
}
System\Application
类必须使用单个参数实例化,该参数指定应用程序的根路径。它尝试使用命名空间自动加载其他类。然后,System\Application
类实例化一个System\Routing\UriRoute
,这是默认的路由机制。UriRoute
接受请求URI并将其分解为段。从这些段中,它确定控制器/动作名称。
除了UriRoute
,还有另外两种路由类型:System\Routing\StaticRoute
和System\Routing\DynamicRoute
。StaticRoute
将URI重映射到控制器/动作名称。这在想要重映射URL,如domain.com/aboutus.html
到一个控制器/动作时非常有用。
$app = new \System\Application(dirname(__FILE__));
$app->addRoute(
'static route',
new \System\Routing\StaticRoute(
'aboutus.html',
'Home',
'aboutus'
)
);
$app->run();
Application
类公开了一个addRoute()
方法,用于添加自定义路由。这个方法接受两个参数。第一个是路由名称,用于简单地引用路由。第二个是路由实例。在上面的示例代码中,已经添加了一个StaticRoute
。这个路由被放入一个集合中,当执行Application->run()
方法时,会遍历这个集合。如上所述,也存在DynamicRoute
。
DynamicRoutes
更加灵活,允许使用正则表达式进行映射。下面的示例展示了如何映射任何以“article”文本开头的URI。
$app = new \System\Application(dirname(__FILE__));
$app->addRoute(
'custom route',
new \System\Routing\DynamicRoute(
'/^article/',
'Article',
'view'
)
);
...
如上所述,路由被放入一个集合中。最后添加的路由是第一个执行的路由。注意,默认的UriRoute
也在集合中,因为它是Application
类添加的第一个路由,所以它是最后一个执行的路由。这确保了如果自定义路由没有匹配,那么UriRoute
将被使用。所有路由类都继承自System\Routing\Route
。可以通过继承这个类并实现抽象方法execute()
来创建自己的路由。execute()
方法应该返回一个布尔值,指示路由是否有效。
应用程序的生命周期在执行run()
方法时开始。run()
方法将遍历路由集合中的路由。如果匹配了路由,将确定控制器/动作名称并分派控制器。控制器必须继承自System\Controller
。当控制器被实例化时,会调用几个方法。首先是init()
方法,它初始化控制器。这个方法就像类构造函数一样。下一个方法是load()
方法。这个方法旨在被重写。它提供了一种为所有动作执行公共代码的方式。下一个方法是动作方法。动作方法必须返回一个动作结果。动作结果可以是标量、数组或对象。如果返回一个数组,框架将把数组编码为JSON并发送到浏览器。内容类型也会更改为“application/json”。如果返回一个对象,那么该对象必须实现一个public render()
方法,该方法返回一个字符串。另一个动作结果是View
。视图不是显式返回的。如果想返回一个视图,必须在Views
目录中创建视图,然后使用控制器的view()
方法返回视图,如下例代码所示:
public function index(){
// Returns a php template
return $this->view();
}
默认情况下,调用不带参数的view()
方法将返回一个与动作名称相同的视图。如果想返回一个不同的视图,可以将视图名称指定为view()
方法的参数,如下所示:
public function index(){
// Returns a php template
return $this->view('another_view');
}
注意,文件扩展名没有包含在内。