上一篇:Lysine介绍(三)MVC - Application
上一篇提到,Lysine的MVC设计模仿了webpy ,controller类非常简单,光说controller就可以没多少可写的,所以把router也放到一起来说明
Router的职责是:
- 解析http请求的url
- 根据url调用对应的controller
- 把controller的执行结果返回给Application
Router解析url有两种方式:正则匹配和默认匹配
正则匹配就是自己定义一套正则表达式,按照匹配的结果调用对应的Controller
<?php
require_once '/path/to/lysine/core.php';
define('ROOT_DIR', realpath(__DIR__ .'/../'));
$config = array(
'app' => array(
'router' => array(
'map' => array(
'#^/hi/([^/]+)$#' => '\Controller\Hi',
'#^/(.*)#' => '\Controller\Index',
),
),
),
);
Lysine\Config::import($config);
$response = app()->run();
echo $response;
以上配置的意思就是:
所有匹配'#^/hi/([^/]+)$#'正则表达式的url都用\Controller\Hi处理
'#^/(.*)#'能够匹配所有的url,所以如果前面没有匹配到的,都默认用\Controller\Index处理
<?php
namespace \Controller;
class Index {
public function get() {
return 'Hello, world!';
}
}
class Hi {
public funciton get($name) {
return "Hi, {$name}!";
}
}
- \Controller\Hi不用继承任何abstract controller类,直接声明即可
- 正则表达式括号匹配到的内容会被作为参数直接传递给Controller对应的方法
- 如果是http get访问,就调用controller get()方法,如果是http post访问,就调用controller post()方法
- 返回的内容以return的方式返回,不应该在controller里直接echo
按照以上代码,如果访问/hi/lysine,网页就会显示"Hi, lysine!",如果访问/not/found,就会显示"Hello, world!"
除了正则表达式匹配之外,Lysine默认也会尝试根据url查找对应的controller,比如:
/user 对应 \Controller\User
/user/login 对应 \Controller\User\Login
/user/get/topic 对应 \Controller\User\Get\Topic
你肯定已经看出来了,这不过是url路径对应controller的一个简单转换而已
最初的设计只提供了webpy风格的正则表达式路由,后来觉得如果每加一个新的页面都需要加一条正则表达式,有时候也挺不方便的,所以就加了后一种路由方式
首先会尝试使用正则方式路由,如果没有找到就尝试简单的路径转换方式路由,如果两种方式都没找到就会抛出一个404异常
controller可以接受的http请求方法是get、post、put、delete,现代浏览器基本都不支持put、delete方法访问,所以这两个方法是通过post模拟,可以通过post _method参数声明方法,或者http request hearder里面声明x-http-method-override来声明
<?php
namespace Controller;
class Example {
public function beforeRun($args) {
// 发生于Router调用之前,可以没有
}
public function afterRun($response) {
// 发生于Router调用之后,可以没有
}
public function get() {
// http get
}
public function post() {
// http post
}
public function put() {
// http put
}
public function delete() {
// http delete
}
public function ajax() {
// ajax request
}
public function ajax_get() {
// ajax request, get method
}
public function ajax_post() {
// ajax request, post method
}
public function ajax_put() {
// ajax request, put method
}
public function ajax_delete() {
// ajax request, delete method
}
}
如果通过ajax发起post请求,尝试调用的顺序是:ajax_post() ajax() post(),如果方法都不存在,而且controller也没有定义__call()魔法方法,就抛出406错误(Not Acceptable)
如果发起的方法不是get post put delete中的任意一个,会抛出405异常(Method Not Allowed)
熟悉其它PHP框架的人可能认为这里的Controller,实际上相当于Action而已,没错,你也可以叫它Action :-)
<?php
require_once '/path/to/lysine/core.php';
$config = array(
'app' => array(
'router' => array(
'namespace' => 'My\Action',
'map' => array(
'#^/(.*)#' => '\My\Action\Index',
),
),
),
);
Lysine\Config::import($config);
$response = app()->run();
echo $response;
PS: 以上提到的Controller和Router都是可以替换,在上一篇里有介绍