caohao0591 发表于 2018-5-11 18:36:36

让你的CI框架快10倍

越是简单的东西越是好的,最近在研究PHP的各种框架, 有yaf, phalcon, CI框架,

1、其中Yaf 是PHP国内第一人写的纯C框架, 核心在于路由部分与类的加载功能, 可惜没有数据库ORM操作,极轻量级。

2、phalcon是国外非常火的一个框架,也是一个纯C框架,非常重量级,过于臃肿,文档不太完善。

3、CI也是一个市场占有率非常高的框架,是纯PHP框架,适度轻量级,文档丰富,性能不及 Yaf 的 1/3。


依照上面的原理,我对项目进行了优化升级,在此基础上开发了一个新的轻量级组合框架,命名为 SuperCI:

1、考虑之前做的项目都是CI框架,如果全部推翻,将会有超级多的东西需要修改,所以我将CI引擎替换,但是SuperCI对外提供的调用方式不变,

2、首先我将CI框架的路由部分抽取出来, 替换成Yaf。

3、然后将CI的数据库ORM操作底层引擎替换成Phalcon, 然而这并不是一个全部的Phalcon, 而是将Phalcon所有其它模块全部删除,仅保留DB操作部分,重新编译之后生成的ORM引擎,替换到CI的数据库底层操作,相当于给五菱宏光装上了悍马的发动机,数据库操作性能能提升2倍。

4、代码模块分离,并加入自己写的模块、类库、配置加载类。

5、加入自己的日志记录类

6、替换 PHP 5 到 PHP 7 , 开启代码缓存opcache。

通过以上工作,整体运行性能提升10倍, 线上运行半年,稳定可靠,线上服务器使用减少2/3,框架极度轻量级, 越是简单的东西越是好的。



框架介绍

运行环境: PHP 7 / PHP 5,opcache

依赖扩展: yaf.so ,phalcon.so

注意:官网的phalcon, 在PHP7下,由于phalcon的一个数据库绑定导致的 opcache 会和 phalcon冲突,导致两个不能同时用, 两者都是提升性能的利器,尤其 Opcache,能提升1倍性能, 请用我提供的源码中的tool/phalcon的源码重新编译生成 phalcon.so,这里的源码去掉了phalcon除了数据库DB操作以外的所有功能,而且解决了与opcache冲突的问题。

如果是PHP5需要到phalcon官网去下载扩展。



配置文件:

superci/conf/application.ini

我们看看路由配置部分:

routes.regex.type="regex"
routes.regex.match="#^/list/([^/]*)/([^/]*)#"
routes.regex.route.controller=Index
routes.regex.route.action=action
routes.regex.map.1=name
routes.regex.map.2=value
routes.simple.type="simple"
routes.simple.controller=c
routes.simple.action=m
routes.simple.module=o
控制器有参数c决定,动作有 m 决定。比如如下demo Url:

http://localhost/index.php?c=test&m=manUser&name=bigbox&sex=%E7%94%B7&age=51

程序将被路由到superci/application/controllers/Test.php文件的 TestController::manUserAction方法,其它路由细节参考Yaf框架

class TestController extends Core_Controller
{
    public function manUserAction()
    {
    }
}
入口

superci/index.php

定义目录,加载Yaf_Application

$app = new Yaf_Application(APPPATH . "/conf/application.ini");
$app->bootstrap()->run();
Bootstrap启动过程

文件位于superci/application/bootstrap.php, Yaf的初始化逻辑, 每个_init开头的函数都会被顺序执行,用户也可以在这里添加自己的初始化逻辑

public function _initConfig() {
      $config = Yaf_Application::app()->getConfig();
      Yaf_Registry::set("config", $config);
    }

    public function _initRoute(Yaf_Dispatcher $dispatcher) {
      $router = Yaf_Dispatcher::getInstance()->getRouter();
      $router->addConfig(Yaf_Registry::get("config")->routes);
    }

    public function _initCommon(Yaf_Dispatcher $dispatcher) { //注册插件
      require_once(BASEPATH . "/Request.php");
      require_once(BASEPATH . "/Loader.php");
      require_once(BASEPATH . "/Logger.php");
    }

    public function _initRequest(Yaf_Dispatcher $dispatcher) { //初始化请求
      $dispatcher->setRequest(new Request());
    }

    public function _initPlugins(Yaf_Dispatcher $dispatcher) { //注册插件
      $dispatcher->registerPlugin(new FilterPlugin());
    }

    public function _initException() { //设置异常回调
      include_once(BASEPATH . "/Common.php");
      set_error_handler('_exception_handler');
    }


过滤器插件

在bootstrap.php 中, 有注册插件 _initPlugins ,我们注册了一个过滤器FilterPlugin,插件定义了6个Hook。

触发顺序        名称        触发时机        说明
1        routerStartup        在路由之前触发        这个是7个事件中, 最早的一个. 但是一些全局自定的工作, 还是应该放在Bootstrap中去完成
2        routerShutdown        路由结束之后触发        此时路由一定正确完成, 否则这个事件不会触发
3        dispatchLoopStartup        分发循环开始之前被触发       
4        preDispatch        分发之前触发        如果在一个请求处理过程中, 发生了forward, 则这个事件会被触发多次
5        postDispatch        分发结束之后触发        此时动作已经执行结束, 视图也已经渲染完成. 和preDispatch类似, 此事件也可能触发多次
6        dispatchLoopShutdown        分发循环结束之后触发        此时表示所有的业务逻辑都已经运行完成, 但是响应还没有发送
我们将验签的过程放在路由之前,如果进来的请求,验签失败,则直接报错。

class FilterPlugin extends Yaf_Plugin_Abstract {
    var $params;

    //路由之前调用
    public function routerStartUp ( Yaf_Request_Abstract $request , Yaf_Response_Abstract $response) {
      $this->params = & $request->getParams();

      $this->_auth();
    }

   //验签过程
    protected function _auth()
    {
      //$this->response_error(1, "验签失败");
    }
}


控制层

所有控制器位于:superci/application/controllers 目录,所有控制器继承自Core_Controller方法,里面主要获取GET/POST参数,以及返回数据的处理,Core_Controller继承自 Yaf_Controller_Abstract, init方法会被自动调用,更多细节参考 Yaf 框架控制器。

class TestController extends Core_Controller
{
    public function init()
    {
      parent::init();
      $this->example_model = Loader::model('ExampleModel');
    }

    public function manUserAction()
    {
      $this->logger->LogInfo("manUser: " . createLinkstringUrlencode($this->params));

      //数据返回
      $res = array();
      $res['uid'] = $this->example_model->insert_data($this->params['name'], $this->params['sex'], $this->params['age']);
      ...

      $this->response_success($res);
    }
}

模型层
所有的Model层位于 superci/application/models目录,

通过 $this->example_model = Loader::model('ExampleModel'); 加载模型



VIEW层

视图层参考yaf视图渲染那部分, 我没有写案例。



APP应用配置

所有配置位于 superci/application/config目录

通过 $config = Loader::config('config');参数为 config里面文件名称, 比如上面加载的就是 config.php


页: [1]
查看完整版本: 让你的CI框架快10倍