Lysine介绍(四)MVC - Controller

上一篇:Lysine介绍(三)MVC - Application

 

上一篇提到,Lysine的MVC设计模仿了webpy ,controller类非常简单,光说controller就可以没多少可写的,所以把router也放到一起来说明

 

Router的职责是:

  1. 解析http请求的url
  2. 根据url调用对应的controller
  3. 把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}!";
    }
}

 

  1. \Controller\Hi不用继承任何abstract controller类,直接声明即可
  2. 正则表达式括号匹配到的内容会被作为参数直接传递给Controller对应的方法
  3. 如果是http get访问,就调用controller get()方法,如果是http post访问,就调用controller post()方法
  4. 返回的内容以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都是可以替换,在上一篇里有介绍

 

下一篇:Lysine介绍(五)MVC - View

你可能感兴趣的:(mvc,Ajax,框架,PHP,正则表达式)