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 @@
@@ -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 @@ -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 *
*