Version 2.4.0 - marmot-cn/marmot-framework GitHub Wiki

2.4.0

概述

1. 代码隔离

框架修改方向基于代码可复用模式. 内部有应用场景如下:

  • 一套代码需要分别部署多个地方
  • 该代码部分功能不变, 部分功能会根据需求改动

所以这次修改方向为:

  • 应用层代码抽离为composer应用代码示例.
  • 框架代码抽离为composer包.
  • 需要额外变动的代码则自己集成父类在修改.

2. mock

添加mock支持, 添加额外的适配器xxxMockAdapter. 用header来控制输出真实接口或者mock接口.

详细修改

1. mock

是否使用mock接口.

--header "mock-status:1"

mock-error

用来模拟错误输出

--header "mock:1" --header "mock-error:10"

添加mockAdapter

针对使用六边形模型, 添加自己的mockAdapter. 具体可见同步更新样例代码

2.Application.php

每个业务代码需要实现自己的Application.php

<?php
namespace Marmot\Application;

use Marmot\Framework\Application\IApplication;

define('APPLICATION_ROOT', dirname(__FILE__) . DIRECTORY_SEPARATOR);

class Application implements IApplication
{
	//默认路由
    public function getIndexRoute() : array
    {
        return ['GET', '/', ['Marmot\Application\Home\Controller\IndexController','index']];
    }
	
	//返回路由规则
    public function getRouteRules() : array
    {
        return include_once APPLICATION_ROOT.'routeRules.php';
    }
	
	//声明错误常量
    public function initErrorConfig() : void
    {
        include_once APPLICATION_ROOT.'errorConfig.php';
    }
	
	//返回错误描述信息
    public function getErrorDescriptions() : array
    {
        return include_once APPLICATION_ROOT.'./errorDescriptionConfig.php';
    }
	
	//声明全局常量
    public function initConfig() : void
    {
        include_once APPLICATION_ROOT.'config.php';
    }
}

3.Core.php

<?php
/**
 * core 核心文件
 *
 * @author  chloroplast1983
 * @version 1.0.20131007
 */

namespace Marmot;

use Marmot\Framework\Classes\Error;
use Marmot\Framework\MarmotCore;
use Marmot\Framework\Application\IApplication;

//需要自己实现的Application
use Marmot\Application\Application;

define('APP_ROOT', dirname(__FILE__) . DIRECTORY_SEPARATOR);

/**
 * 文件核心类
 *
 * @author  chloroplast1983
 * @version 1.0.20130916
 */
class Core extends MarmotCore
{
    
    private static $instance;

    /**
     * 使用单例封装全局函数的core调用
     */
    public static function &getInstance()
    {
        if (!self::$instance instanceof self) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 单元测试专用启动路程,用于引导phpunit,bootstrap的路由文件进入.
     * 在这里我们要实现如下功能:
     * 1. 自动加载
     * 2. 初始化容器
     * 3. 初始化缓存
     * 4. 初始化测试持久层存储,用于测试数据库和程序分离
     */
    public function initTest()
    {
        $this->initAutoload();//autoload
        $this->initTestEnv();//初始化测试环境
        $this->initContainer();//引入容器
        $this->initEnv();//初始化环境
        $this->initCache();//初始化缓存使用
        $this->initDb();//初始化mysql
        $this->initMongo();
        $this->initError();
    }
    
   protected function initApplication() : void
    {
        $this->application = new Application();
    }

    protected function getApplication() : IApplication
    {
        return $this->application;
    }

    /**
     * 自动加载方法,这里分为2个部分.这里的借鉴了yii框架的自动加载
     * 符合PSR4自动加载规范
     *
     * 1. 加载第三方的autoload,主要是composer管理的第三方依赖
     * 2. 核心框架自己的autoload
     *    2.1 核心文件主要是通过映射关系载入的,原来使用的是淘宝的一套开源的autoload,
     *        但是考虑其功能过于繁重,这里改为用文件映射
     *    2.2 应用文件(Application)主要是通过命名规则映射
     */
    protected function initAutoload()
    {
        //加载框架Application文件的autoload,匿名函数 -- 开始
        spl_autoload_register(
            function ($className) {
                $classFile = str_replace('\\', '/', $className) . '.class.php';
                $classFile = APP_ROOT.'Application/'.$classFile;
                if (file_exists($classFile)) {
                      include_once $classFile;
                }
            }
        );
        //加载ut测试文件
        spl_autoload_register(
            function ($className) {

                $unitTestFile = str_replace('\\', '/', $className) . '.php';
                $unitTestFile = APP_ROOT.'tests/UnitTest/Application/'.$unitTestFile;

                if (file_exists($unitTestFile)) {
                    include_once $unitTestFile;
                }
            }
        );
        加载框架Application文件的autoload,匿名函数 -- 开始
    }

    private function initTestEnv()
    {
        $_ENV['APP_ENV'] = 'test';
    }

    protected function getAppPath() : string
    {
        return APP_ROOT;
    }

    /**
     * 初始化数据库
     *
     * @version 1.0.20160204
     */
    protected function initDb()
    {
        parent::initMysql();
        parent::initMongo();
    }

    protected function initCache()
    {
        parent::initMemcached(self::$container->get('memcached.serevice'));
    }

4.其他改动

  • 添加IRestfulTranslator, 在使用GuzzleAdapter时候需要返回该接口的翻译器. 具体翻译器代码不用改动, 只用修改该返回实现即可.
  • RowCacheQuery, RowQuery添加fetchOne, fetchList, 对代码可读性进行兼容处理, get表示轻量级获取, fetch表示远程抓取. 后续代码尽量使用fetchOnefetchList