diff --git a/.env.example b/.env.example index 0c8d951..e09949b 100644 --- a/.env.example +++ b/.env.example @@ -8,6 +8,19 @@ 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 [nosql] support = redis diff --git a/README-CN.md b/README-CN.md index c19e423..0411f7f 100644 --- a/README-CN.md +++ b/README-CN.md @@ -3,8 +3,8 @@
@@ -115,7 +115,7 @@ vendor [composer目录] ├── pre-commit [git pre-commit预commit钩子示例文件] ├── commit-msg [git commit-msg示例文件] .babelrc [babel配置文件] -.env [环境变量文件] +.env.example [环境变量示例文件] .gitignore [git忽略文件配置] build [php打包脚本] cli [框架cli模式运行脚本] @@ -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,6 +205,14 @@ require('../framework/run.php'); 框架中所有的异常输出和控制器输出都是json格式,因为我认为在前后端完全分离的今天,这是很友善的,目前我们不需要再去考虑别的东西。 +##### 请求参数校验,目前提供必传,长度,数字类型校验,使用如下 +``` +$request = App::$container->getSingle('request'); +$request->check('username', 'require'); +$request->check('password', 'length', 12); +$request->check('code', 'number'); +``` + [[file: framework/Request.php](https://github.com/TIGERB/easy-php/blob/master/framework/Request.php)] [[file: framework/Response.php](https://github.com/TIGERB/easy-php/blob/master/framework/Response.php)] @@ -669,3 +702,8 @@ cp ./.git-hooks/* ./git/hooks - 懒加载优化框架加载流程 - 变更Helper助手类的成员方法为框架函数,简化使用提高生产效率 - 性能测试和优化 + +- v0.6.9(2017/05/21) + - 提供更友善的开发api帮助 + + 请求参数校验:require/length/number + - 支持mysql主从配置 diff --git a/README.md b/README.md index d58f228..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
@@ -31,7 +31,7 @@ Entry file ----> Register autoload function
----> View
```
-In addition, unit test, nosql support, api documents and some auxiliary scripts, etc. Finnally, My framework directory as follows:
+In addition, unit test, nosql support, api documents and some auxiliary scripts, e.g. Finnally, My framework directory as follows:
# Project Directory Structure
@@ -114,7 +114,7 @@ vendor [composer vendor directory]
├── pre-commit [git pre-commit example file]
├── commit-msg [git commit-msg example file]
.babelrc [babel config file]
-.env [the environment variables file]
+.env.example [the environment variables example file]
.gitignore [git ignore config file]
build [build php code to phar file script]
cli [run this framework with the php cli mode]
@@ -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,6 +202,14 @@ 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 = App::$container->getSingle('request');
+$request->check('username', 'require');
+$request->check('password', 'length', 12);
+$request->check('code', 'number');
+```
+
[[file: framework/Request.php](https://github.com/TIGERB/easy-php/blob/master/framework/Request.php)]
[[file: framework/Response.php](https://github.com/TIGERB/easy-php/blob/master/framework/Response.php)]
@@ -663,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 0a03c42..c9e12ab 100644
--- a/app/demo/controllers/DbOperationDemo.php
+++ b/app/demo/controllers/DbOperationDemo.php
@@ -46,9 +46,13 @@ public function dbFindDemo()
->orderBy('id asc')
->findOne();
$sql = $instance->sql;
+ $database = $instance->masterSlave;
- // return $sql;
- return $res;
+ return [
+ 'db' => $database,
+ 'sql' => $sql,
+ 'res' => $res
+ ];
}
/**
@@ -69,6 +73,7 @@ public function dbFindAllDemo()
->limit(5)
->findAll(['id','create_at']);
$sql = $instance->sql;
+ $database = $instance->masterSlave;
// return $sql;
return $res;
@@ -104,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/app/demo/controllers/Index.php b/app/demo/controllers/Index.php
index 90e06fe..1af3c89 100644
--- a/app/demo/controllers/Index.php
+++ b/app/demo/controllers/Index.php
@@ -10,7 +10,7 @@
namespace App\Demo\Controllers;
use Framework\App;
-use Framework\Loger;
+use Framework\Logger;
/**
* Index Controller
@@ -42,12 +42,16 @@ public function hello()
*
* @param string $username 用户名
* @param string $password 密码
- * @example domain/Demo/Index/get?username=test&password=123456
+ * @param number code 验证码
+ * @example domain/Demo/Index/test?username=tigerb&password=123456789987&code=123456
* @return json
*/
public function test()
{
$request = App::$container->getSingle('request');
+ $request->check('username', 'require');
+ $request->check('password', 'length', 12);
+ $request->check('code', 'number');
return [
'username' => $request->get('username', 'default value')
];
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/config/database.php b/config/database.php
index 91ed125..9e89b2f 100644
--- a/config/database.php
+++ b/config/database.php
@@ -10,13 +10,28 @@
********************************************/
return [
- /* 默认配置 */
+ /* 主库配置 */
'database' => [
'dbtype' => env('database')['dbtype'],
'dbprefix' => env('database')['dbprefix'],
'dbname' => env('database')['dbname'],
'dbhost' => env('database')['dbhost'],
'username' => env('database')['username'],
- 'password' => env('database')['password']
+ 'password' => env('database')['password'],
+ 'slave' => explode(',', env('database')['slave'])
+ ],
+ /* 从库0配置 */
+ 'database-slave-0' => [
+ 'dbname' => env('database-slave-0')['dbname'],
+ 'dbhost' => env('database-slave-0')['dbhost'],
+ 'username' => env('database-slave-0')['username'],
+ 'password' => env('database-slave-0')['password'],
+ ],
+ /* 从库1配置 */
+ 'database-slave-1' => [
+ 'dbname' => env('database-slave-1')['dbname'],
+ 'dbhost' => env('database-slave-1')['dbhost'],
+ 'username' => env('database-slave-1')['username'],
+ 'password' => env('database-slave-1')['password'],
]
];
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/Request.php b/framework/Request.php
index 1b1f479..bb3ba35 100644
--- a/framework/Request.php
+++ b/framework/Request.php
@@ -11,6 +11,8 @@
namespace Framework;
+use Framework\Exceptions\CoreHttpException;
+
/**
* 请求
*
@@ -154,21 +156,6 @@ public function __construct(App $app)
$this->loadEnv($app);
}
- /**
- * 加载环境参数
- *
- * @param App $app 框架实例
- * @return void
- */
- public function loadEnv(App $app)
- {
- $env = parse_ini_file($app->rootPath . '/.env', true);
- if ($env === false) {
- throw CoreHttpException('load env fail', 500);
- }
- $this->envParams = array_merge($_ENV, $env);
- }
-
/**
* 魔法函数__get.
*
@@ -292,4 +279,65 @@ public function env($value = '')
}
return '';
}
+
+ /**
+ * 加载环境参数
+ *
+ * @param App $app 框架实例
+ * @return void
+ */
+ public function loadEnv(App $app)
+ {
+ $env = parse_ini_file($app->rootPath . '/.env', true);
+ if ($env === false) {
+ throw CoreHttpException('load env fail', 500);
+ }
+ $this->envParams = array_merge($_ENV, $env);
+ }
+
+ /**
+ * 参数验证
+ *
+ * 支持必传参数验证,参数长度验证,参数类型验证
+ *
+ * @param string $paramName 参数名
+ * @param string $rule 规则
+ * @return mixed
+ */
+ public function check($paramName = '', $rule = '', $length = 0)
+ {
+ if (! is_int($length)) {
+ throw new CoreHttpException(
+ 400,
+ "length type is not int"
+ );
+ }
+
+ if ($rule === 'require') {
+ if (! empty($this->request($paramName))) {
+ return;
+ }
+ throw new CoreHttpException(404, "param {$paramName}");
+ }
+
+ if ($rule === 'length') {
+ if (strlen($this->request($paramName)) === $length) {
+ return;
+ }
+ throw new CoreHttpException(
+ 400,
+ "param {$paramName} length is not {$length}"
+ );
+ }
+
+ if ($rule === 'number') {
+ if (is_numeric($this->request($paramName))) {
+ return;
+ }
+ throw new CoreHttpException(
+ 400,
+ "{$paramName} type is not number"
+ );
+ }
+ }
}
diff --git a/framework/handles/ExceptionHandle.php b/framework/handles/ExceptionHandle.php
index 3dc5bac..eb17385 100644
--- a/framework/handles/ExceptionHandle.php
+++ b/framework/handles/ExceptionHandle.php
@@ -49,7 +49,15 @@ public function register(App $app)
*/
public function exceptionHandler($exception)
{
- throw $exception;
- }
+ $exceptionInfo = [
+ 'code' => $exception->getCode(),
+ 'message' => $exception->getMessage(),
+ 'file' => $exception->getFile(),
+ 'line' => $exception->getLine(),
+ 'trace' => $exception->getTrace(),
+ 'previous' => $exception->getPrevious()
+ ];
+ CoreHttpException::reponseErr($exceptionInfo);
+ }
}
diff --git a/framework/orm/DB.php b/framework/orm/DB.php
index 9571cc3..4757e7c 100644
--- a/framework/orm/DB.php
+++ b/framework/orm/DB.php
@@ -73,12 +73,38 @@ class DB
*/
protected $id = '';
+ /**
+ * 走主库的查寻语句
+ *
+ * @var array
+ */
+ private $master = ['insert', 'update', 'delete'];
+
+ /**
+ * 当前查询主从
+ *
+ * @var string
+ */
+ private $masterSlave = '';
+
+ /**
+ * 数据库配置
+ *
+ * @var array
+ */
+ private $dbConfig = [
+ 'dbhost' => '',
+ 'dbname' => '',
+ 'username' => '',
+ 'password' => ''
+ ];
+
/**
* 构造函数
*/
public function __construct()
{
- $this->init();
+ // $this->init();
}
/**
@@ -96,7 +122,7 @@ public static function table($tableName = '')
if (! empty($prefix)) {
$db->tableName = $prefix . '_' . $db->tableName;
}
- $db->init();
+ // $db->init();
return $db;
}
@@ -104,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();
}
@@ -121,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}";
+ }
+
/**
* 查找一条数据
*
@@ -165,6 +259,7 @@ public function findAll($data = [])
public function save($data = [])
{
$this->insert($data);
+ $this->init();
$functionName = __FUNCTION__;
return $this->dbInstance->$functionName($this);
}
@@ -231,6 +326,7 @@ public function sum($data = '')
public function query($sql = '')
{
$this->querySql($sql);
+ $this->init();
return $this->dbInstance->query($this);
}
@@ -250,6 +346,8 @@ public function buildSql()
if (! empty($this->limit)) {
$this->sql .= $this->limit;
}
+
+ $this->init();
}
/**
@@ -259,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();
}
@@ -273,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();
}
@@ -291,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 3de7afc..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,18 +74,24 @@ class Mysql
private $pdoStatement = '';
/**
- * construct function
+ * 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 __construct()
+ public function __construct(
+ $dbhost = '',
+ $dbname = '',
+ $username = '',
+ $password = '')
{
- $config = APP::$container->getSingle('config');
- $config = $config->config;
- $dbConfig = $config['database'];
- $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;
$this->connect();
}
diff --git a/framework/run.php b/framework/run.php
index 910c616..985160c 100644
--- a/framework/run.php
+++ b/framework/run.php
@@ -65,13 +65,10 @@
return new ErrorHandle();
});
- // $app->load(function () {
- // // 加载异常处理机制 由于本文件全局catch了异常 所以不存在未捕获异常
- // // 可省略注册未捕获异常Handle
- // // Loading exception handle.
- // // I'm not used it, because this file catch all exception
- // return new ExceptionHandle();
- // });
+ $app->load(function () {
+ // 加载异常处理机制 Loading exception handle.
+ return new ExceptionHandle();
+ });
$app->load(function () {
// 加载nosql机制 Loading nosql handle
@@ -117,7 +114,7 @@
$app->response(function () {
return new Response();
});
-} catch (CoreHttpException $e) {
+} catch (CoreHttException $e) {
/**
* 捕获异常
*
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 *
*