From 4ed7253b18b9925482c1e60e180f6008b1ef4626 Mon Sep 17 00:00:00 2001 From: tigerb <624661874@qq.com> Date: Tue, 23 May 2017 01:14:43 +0800 Subject: [PATCH] feat(db): master and slave support :sparkles: --- README-CN.md | 31 +++++- README.md | 37 +++++++- app/demo/controllers/DbOperationDemo.php | 15 ++- composer.json | 7 +- framework/Container.php | 19 +++- framework/orm/DB.php | 114 +++++++++++++++++++++-- framework/orm/db/Mysql.php | 64 +++---------- public/index.php | 2 +- 8 files changed, 210 insertions(+), 79 deletions(-) diff --git a/README-CN.md b/README-CN.md index ca6a05a..0411f7f 100644 --- a/README-CN.md +++ b/README-CN.md @@ -3,8 +3,8 @@

Build Status PHP Version -Version -Framework Size +Version +Framework Size Framework Phar Size License

@@ -171,6 +171,31 @@ require('../framework/run.php'); 加载框架自定义和用户自定义的配置文件。 +例如,数据库主从配置.env文件参数示例: + +``` +[database] +dbtype = mysqldb +dbprefix = easy +dbname = easyphp +dbhost = localhost +username = easyphp +password = easyphp +slave = 0,1 + +[database-slave-0] +dbname = easyphp +dbhost = localhost +username = easyphp +password = easyphp + +[database-slave-1] +dbname = easyphp +dbhost = localhost +username = easyphp +password = easyphp +``` + [[file: framework/hanles/ConfigHandle.php](https://github.com/TIGERB/easy-php/blob/master/framework/handles/ConfigHandle.php)] ## 输入和输出 @@ -180,7 +205,7 @@ require('../framework/run.php'); 框架中所有的异常输出和控制器输出都是json格式,因为我认为在前后端完全分离的今天,这是很友善的,目前我们不需要再去考虑别的东西。 -# 请求参数校验,目前提供必传,长度,数字类型校验,使用如下 +##### 请求参数校验,目前提供必传,长度,数字类型校验,使用如下 ``` $request = App::$container->getSingle('request'); $request->check('username', 'require'); diff --git a/README.md b/README.md index d0d9341..282cdc5 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@

Build Status PHP Version -Version -Framework Size +Version +Framework Size Framework Phar Size License

-

A lightweight PHP framework for studying

+

A Faster Lightweight Full-Stack PHP Framework

中文版 

@@ -168,6 +168,31 @@ Register a function by used set_exception_handler to handle the exception which Loading framework-defined and user-defined config files. +For example,the master-salve database config: + +``` +[database] +dbtype = mysqldb +dbprefix = easy +dbname = easyphp +dbhost = localhost +username = easyphp +password = easyphp +slave = 0,1 + +[database-slave-0] +dbname = easyphp +dbhost = localhost +username = easyphp +password = easyphp + +[database-slave-1] +dbname = easyphp +dbhost = localhost +username = easyphp +password = easyphp +``` + [[file: framework/hanles/ConfigHandle.php](https://github.com/TIGERB/easy-php/blob/master/framework/handles/ConfigHandle.php)] ## Request&Response Module @@ -177,7 +202,7 @@ Loading framework-defined and user-defined config files. All output is json in the framework, neithor framework's core error or business logic's output, beacuse I think is friendly. -# Request param check, Support require/length/number check at present. Use as follows: +##### Request param check, Support require/length/number check at present. Use as follows: ``` $request = App::$container->getSingle('request'); $request->check('username', 'require'); @@ -671,3 +696,7 @@ project address: [https://github.com/TIGERB/easy-php](https://github.com/TIGERB/ - The performance test and optimize - Use the lazy load thought to optimize the framework - Change Helper's method to the framework's function +- v0.6.9(2017/05/22) + - more friendly for api develop process + + request param check:require/length/number + - support master-salve config for db diff --git a/app/demo/controllers/DbOperationDemo.php b/app/demo/controllers/DbOperationDemo.php index 71a6c21..c9e12ab 100644 --- a/app/demo/controllers/DbOperationDemo.php +++ b/app/demo/controllers/DbOperationDemo.php @@ -48,8 +48,11 @@ public function dbFindDemo() $sql = $instance->sql; $database = $instance->masterSlave; - // return $sql; - return $res; + return [ + 'db' => $database, + 'sql' => $sql, + 'res' => $res + ]; } /** @@ -106,8 +109,12 @@ public function dbSaveDemo() } return [ - 'user_id' => $userId, - 'test_id' => $testId + 'db' => $user->masterSlave, + 'sql' => $user->sql, + 'res' => [ + 'user_id' => $userId, + 'test_id' => $testId + ] ]; } diff --git a/composer.json b/composer.json index 07461de..e9ab6f0 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "tigerb/easy-php", - "description": "A lightweight PHP framework for studying", - "version": "0.6.8", + "description": "A Faster Lightweight Full-Stack PHP Framework", + "version": "0.6.9", "type": "framework, easy-php, php framework", "homepage": "http://php.tiegrb.cn/", "license": "MIT", @@ -24,7 +24,8 @@ "composer dump-autoload --optimize" ], "post-root-project-cmd": [ - "composer install" + "composer install", + "cp ./.git-hooks/* ./git/hooks" ], "pre-status-cmd": [ "cp .env.example .env", diff --git a/framework/Container.php b/framework/Container.php index e854a58..4430adf 100644 --- a/framework/Container.php +++ b/framework/Container.php @@ -108,8 +108,7 @@ public function setSingle($alias = '', $object = '') if (array_key_exists($alias, $this->instanceMap)) { return $this->instanceMap[$alias]; } - $this->instanceMap[$alias] = $object(); - return $this->instanceMap[$alias]; + $this->instanceMap[$alias] = $object; } if (is_object($alias)) { $className = get_class($alias); @@ -144,14 +143,24 @@ public function setSingle($alias = '', $object = '') * * get a sington instance * - * @param string $alias 类名或别名 + * @param string $alias 类名或别名 + * @param Closure $closure 闭包 * @return object */ - public function getSingle($alias = '') + public function getSingle($alias = '', $closure = '') { if (array_key_exists($alias, $this->instanceMap)) { - return $this->instanceMap[$alias]; + $instance = $this->instanceMap[$alias]; + if (is_callable($instance)) { + return $instance(); + } + return $instance; + } + + if (is_callable($closure)) { + return $this->instanceMap[$alias] = $closure(); } + throw new CoreHttpException( 404, 'Class:' . $alias diff --git a/framework/orm/DB.php b/framework/orm/DB.php index b3cb8e7..4757e7c 100644 --- a/framework/orm/DB.php +++ b/framework/orm/DB.php @@ -73,19 +73,38 @@ class DB */ protected $id = ''; + /** + * 走主库的查寻语句 + * + * @var array + */ + private $master = ['insert', 'update', 'delete']; + /** * 当前查询主从 * - * @var object + * @var string */ private $masterSlave = ''; + /** + * 数据库配置 + * + * @var array + */ + private $dbConfig = [ + 'dbhost' => '', + 'dbname' => '', + 'username' => '', + 'password' => '' + ]; + /** * 构造函数 */ public function __construct() { - $this->init(); + // $this->init(); } /** @@ -103,7 +122,7 @@ public static function table($tableName = '') if (! empty($prefix)) { $db->tableName = $prefix . '_' . $db->tableName; } - $db->init(); + // $db->init(); return $db; } @@ -111,12 +130,17 @@ public static function table($tableName = '') /** * 初始化策略 * + * @param $masterOrSlave 初始化主库还是从库 * @return void */ - public function init() + public function init($masterOrSlave = '') { $config = APP::$container->getSingle('config'); $this->dbtype = $config->config['database']['dbtype']; + if (! empty($masterOrSlave)) { + $this->masterSlave = $masterOrSlave; + } + $this->isMasterOrSlave(); $this->decide(); } @@ -128,14 +152,77 @@ public function init() public function decide() { $dbStrategyName = $this->dbStrategyMap[$this->dbtype]; - $this->dbInstance = APP::$container->setSingle( - $this->dbtype, - function () use ($dbStrategyName) { - return new $dbStrategyName(); + $dbConfig = $this->dbConfig; + $this->dbInstance = APP::$container->getSingle( + "{$this->dbtype}-{$this->masterSlave}", + function () use ($dbStrategyName, $dbConfig) { + return new $dbStrategyName( + $dbConfig['dbhost'], + $dbConfig['dbname'], + $dbConfig['username'], + $dbConfig['password'] + ); } ); } + /** + * 判断走主库还是从库 + * + * @return void + */ + public function isMasterOrSlave() + { + if (! empty($this->masterSlave)) { + $this->initMaster(); + return; + } + foreach ($this->master as $v) { + $res = stripos($this->sql, $v); + if ($res === 0 || $res) { + $this->initMaster(); + return; + } + } + $this->initSlave(); + } + + /** + * 初始化主库 + */ + public function initMaster() + { + $config = APP::$container->getSingle('config'); + $dbConfig = $config->config['database']; + $this->dbConfig['dbhost'] = $dbConfig['dbhost']; + $this->dbConfig['dbname'] = $dbConfig['dbname']; + $this->dbConfig['username'] = $dbConfig['username']; + $this->dbConfig['password'] = $dbConfig['password']; + + $this->masterSlave = 'master'; + } + + /** + * 初始化从库 + */ + public function initSlave() + { + $config = APP::$container->getSingle('config'); + if (! isset($config->config['database']['slave'])) { + $this->initMaster(); + return; + } + $slave = $config->config['database']['slave']; + $randSlave = $slave[array_rand($slave)]; + $dbConfig = $config->config["database-slave-{$randSlave}"]; + $this->dbConfig['dbhost'] = $dbConfig['dbhost']; + $this->dbConfig['dbname'] = $dbConfig['dbname']; + $this->dbConfig['username'] = $dbConfig['username']; + $this->dbConfig['password'] = $dbConfig['password']; + + $this->masterSlave = "slave-{$randSlave}"; + } + /** * 查找一条数据 * @@ -172,6 +259,7 @@ public function findAll($data = []) public function save($data = []) { $this->insert($data); + $this->init(); $functionName = __FUNCTION__; return $this->dbInstance->$functionName($this); } @@ -238,6 +326,7 @@ public function sum($data = '') public function query($sql = '') { $this->querySql($sql); + $this->init(); return $this->dbInstance->query($this); } @@ -257,6 +346,8 @@ public function buildSql() if (! empty($this->limit)) { $this->sql .= $this->limit; } + + $this->init(); } /** @@ -266,10 +357,11 @@ public function buildSql() */ public static function beginTransaction() { - $instance = APP::$container->setSingle('DB', function () { + $instance = APP::$container->getSingle('DB', function () { return new DB(); } ); + $instance->init('master'); $instance->dbInstance->beginTransaction(); } @@ -280,10 +372,11 @@ public static function beginTransaction() */ public static function commit() { - $instance = APP::$container->setSingle('DB', function () { + $instance = APP::$container->getSingle('DB', function () { return new DB(); } ); + $instance->init('master'); $instance->dbInstance->commit(); } @@ -298,6 +391,7 @@ public static function rollBack() return new DB(); } ); + $instance->init('master'); $instance->dbInstance->rollBack(); } diff --git a/framework/orm/db/Mysql.php b/framework/orm/db/Mysql.php index ea93388..bfff72a 100644 --- a/framework/orm/db/Mysql.php +++ b/framework/orm/db/Mysql.php @@ -11,7 +11,6 @@ namespace Framework\Orm\Db; -use Framework\App; use Framework\Orm\DB; use Framework\Exceptions\CoreHttpException; use PDO; @@ -75,52 +74,25 @@ class Mysql private $pdoStatement = ''; /** - * construct function - */ - public function __construct() - { - - } - - /** - * 初始化主库 - */ - public function initMaster(DB $db) - { - - $config = APP::$container->getSingle('config'); - $config = $config->config; - $dbConfig = $config['database']; - $this->dbhost = $dbConfig['dbhost']; - $this->dbname = $dbConfig['dbname']; - $this->dsn = "mysql:dbname={$this->dbname};host={$this->dbhost};"; - $this->username = $dbConfig['username']; - $this->password = $dbConfig['password']; - - $db->masterSlave = 'master'; - $this->connect(); - } - - /** - * 初始化从库 + * init mysql driver by pdo + * + * @param string $dbhost host + * @param string $dbname database name + * @param string $username database username + * @param string $password password */ - public function initSlave(DB $db) + public function __construct( + $dbhost = '', + $dbname = '', + $username = '', + $password = '') { - $config = APP::$container->getSingle('config'); - if (! isset($config->config['database']['slave'])) { - $this->initMaster($db); - return; - } - $slave = $config->config['database']['slave']; - $randSlave = $slave[array_rand($slave)]; - $dbConfig = $config->config["database-slave-{$randSlave}"]; - $this->dbhost = $dbConfig['dbhost']; - $this->dbname = $dbConfig['dbname']; + $this->dbhost = $dbhost; + $this->dbname = $dbname; $this->dsn = "mysql:dbname={$this->dbname};host={$this->dbhost};"; - $this->username = $dbConfig['username']; - $this->password = $dbConfig['password']; + $this->username = $username; + $this->password = $password; - $db->masterSlave = "slave-{$randSlave}"; $this->connect(); } @@ -169,7 +141,6 @@ public function __set($name = '', $value = '') */ public function findOne(DB $db) { - $this->initSlave($db); $this->pdoStatement = $this->pdo->prepare($db->sql); $this->bindValue($db); $this->pdoStatement->execute(); @@ -184,7 +155,6 @@ public function findOne(DB $db) */ public function findAll(DB $db) { - $this->initSlave($db); $this->pdoStatement = $this->pdo->prepare($db->sql); $this->bindValue($db); $this->pdoStatement->execute(); @@ -199,7 +169,6 @@ public function findAll(DB $db) */ public function save(DB $db) { - $this->initMaster($db); $this->pdoStatement = $this->pdo->prepare($db->sql); $this->bindValue($db); $res = $this->pdoStatement->execute(); @@ -217,7 +186,6 @@ public function save(DB $db) */ public function delete(DB $db) { - $this->initMaster($db); $this->pdoStatement = $this->pdo->prepare($db->sql); $this->bindValue($db); $this->pdoStatement->execute(); @@ -232,7 +200,6 @@ public function delete(DB $db) */ public function update(DB $db) { - $this->initMaster($db); $this->pdoStatement = $this->pdo->prepare($db->sql); $this->bindValue($db); return $this->pdoStatement->execute(); @@ -246,7 +213,6 @@ public function update(DB $db) */ public function query(DB $db) { - $this->initMaster($db); $res = []; foreach ($this->pdo->query($db->sql, PDO::FETCH_ASSOC) as $v) { $res[] = $v; diff --git a/public/index.php b/public/index.php index 097d8f4..ee2df0e 100644 --- a/public/index.php +++ b/public/index.php @@ -7,7 +7,7 @@ * TIERGB * * * * * - * Version: 0.6.8 * + * Version: 0.6.9 * ********************************************/ // 载入框架运行文件