PHP搭建自己的web框架-控制器

        控制器是整个网站的逻辑实现主体,是最核心部分。

        简单的,控制器是一个类方法,调用model并显示数据。

        不过,一般来说功能和业务都不会很简单,会自然形成或逐渐演化到一定的功能层次,形成相对清晰的层次和功能划分。

接口层要:

        针对不同的端不同的权限控制或者参数校验,分出接口层,直接面对客户端。

       1. 参数获取、过滤。如果不需要存到数据库,不需要回显到网页,可直接使用$_GET/$_POST_/$_REQUEST,否则过滤后再获取,写一个get方法,如

       $name=g_req('name',$default,$_GET);

       2. 是否使用session。有些会在框架里自动启动,我们是到具体接口才决定是否使用(大部分在构造函数里启动)。因为不同的端是使用不同的登录控制的,页面是用到session,但开放接口用了token,并不需要使用到session功能。某些页面操作可能也不会使用session,也不需要启动。为了集群部署,一般都把session放DB或缓存,启动session意味着一个请求里一来一回的读写操作,甚至两读一写,当然可以优化,后面会讲到。

       3.显示网页/返回数据。

业务层:

        虽然有不同的端进来,但是调用的业务都一样的,比如登录处理,那么把登录处理作为一个业务封装起来,接口层把关后,就可调用相应的业务来处理。

        业务层与业务相关,可以调用其它业务作为子业务;可以组合其它功能完成某项任务,如记录日志;调用DAO层来存取数据;调用后台接口获得数据等等。

       返回给接口的话,要么是数据,要么是状态值,要么是bool,接口要根据情况回复客户端的调用。

数据访问层:

        业务层把数据存取功能交接给DAO层,DAO层通过不同的数据库驱动操作数据库。有些是通过模型来做这项工作,但我们基本没有模型,主要用数组,直接就是DAO层跟数据库打交道,将数据转化为数组内容。DAO层还做些基本的数据转换等处理,还有缓存处理(前端缓存,xcache及redis)。


     以上是控制器的层次结构,层次结构是一种内联结构,是控制器自己的组织关系。但是接口层是控制主要负责人,有更大的灵活性和控制权,是MVC中的C,也是整个框架的中心的意思,纵向连结自身层次结构,横向连结着外部关系如,路由(入口)、视图(出口)。


控制器的继承--网站分解结构

      简单地,控制器接口就一个类文件,不继承其它类。但更常见的做法是抽象一些共性的,通过一个父类,或父父类,加上组合来完成(如一个$view模板引擎)。比如PC端有一个PC端的父类,移动端有一个移动端的父类,因为它们都要显示网页,所以它们的父类又是某个父类的子类,通过继承来分解网站结构。如果有一个首页,可以继承相应的父类,然后只要实现主体部分,比如body的显示即可:

class Action{
    protected $view;
}

class PCAction extends Action{
    $header_tpl = 'header.tpl';
    $body_tpl = '';
    $footer_tpl = 'footer.tpl';
    function display(){
	$this->view->display('pc.tpl');//pc.tpl包括了头、尾、body的布局</span>
    }
}

class Homepage extends PCAction{
    function index(){
        $this->body_tpl = 'homepage.tpl';
        $this->display();
    }
}

如果主页又能细分为左菜单,右内容,可继续分解子类:

class Homepage extends PCAction{
    $left_tpl = 'body_left.tpl';
    $content_tpl = '';
	
    function __construct() {
        $this->body_tpl = 'homepage.tpl';//包含了$left_tpl和$content_tpl布局
    }
}

class IntroHomepage extends Homepage{
	
    function index(){
        $this->content_tpl = 'intro_content.tpl';
        $this->display();
    }
}

如果是开放API接口,输出json/xml,那继承关系相对会比较简单。


路由与控制器

回顾上一节关于路由的实现:

$class = 'user';  
$method = 'info';
$instance = new $class ();
$ismobile = isMobile();
$instance->IsMobile($ismobile);  //基类参数设置
if (method_exists ( $class, $method )) {
	$instance->before();//基类抽象方法
	$instance->$method ( );
	$instance->after(); //基类抽象方法
} else {	
	Problem::send400 ();
}

基类控制器:

class Action{
    protected $isMobile;
    protected $view;
    function isMobile($bool){}

    function before(){}
	
    function after(){}
}
(以上是示例,我们项目基类并没有before/after/isMobile等方法)

下面是业务控制器:

class user extends Action{
    function before(){
        //执行info方法前执行的方法
    }
	
    function after(){
        //执行info方法后执行的方法
    }
	
    function info(){
        //获取参数
        //调用业务方法
        //输出数据
    }
}

从上面代码可以看出,可以通过一个基类控制器与路由器交互,参数传递,屏蔽与业务无关的细节。基类控制器还可以预先作一些参数过滤和安全控制等预处理功能,业务控制器作为子类可以获得父类的功能和参数。从这些方面来看,有一个基类控制来对接路由,还是很方便的,但又要防止过度去做预处理。


控制器与逻辑

        不是指具体的业务逻辑,而是指业务组合逻辑。

        比如登录控制;比如发表文章,发表前权限控制,发表后后,增加积分、记录日志。

        待续。。。



控制器与输出

控制器处理后的数据要输出给客户端,一般有两种方式,一种是把在控制器中结果返回去,由框架处理;另一种直接由控制器直接echo输出返回。

比如现在常用的是使用JOSN格式输出结果,那么简单地封装一个方法,需要时由控制器调用即可:

	public  function json_return($data) {
		header ( 'HTTP/1.1 200 OK' );
		header ( "Content-Type: application/json" );
		header ( "Cache-Control: no-store" );
		echo json_encode ( $data );
		exit ();
	}


而对于网页视图的输出,因为与页面模板引擎有关系,将会在下节中介绍。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值