From bcb2ab2a61c6c29c503b177140258c1c04c42034 Mon Sep 17 00:00:00 2001
From: top_nuomi <1130395124@qq.com>
Date: Sat, 31 Aug 2019 17:02:32 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0README=E6=96=87=E4=BB=B6?=
=?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=BA=93=E7=AB=AF?=
=?UTF-8?q?=E5=8F=A3=E9=85=8D=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 591 +++++++++++-------
framework/config/config.php | 1 +
framework/library/database/driver/MySQLi.php | 2 +-
.../database/driver/ObjectForMySQL.php | 2 +-
4 files changed, 367 insertions(+), 229 deletions(-)
diff --git a/README.md b/README.md
index 84a3d1c..e57b4bb 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,74 @@
# TOP-Framework
*这是一个部分代码源自三年前毕业设计中的代码集合,后经过一系列重构,形成的一套框架。在此准备写一个文档。*
+## 目录结构
+遵循PSR-2规范的编码风格,遵循PSR-4自动加载规范(非composer,框架可脱离composer运行)。
+基本目录结构:
+```
+-application 应用目录
+-framework 框架所在目录
+ -config 默认配置文件目录
+ -create 自动生成模块
+ -extend 功能扩展类目录
+ -library 核心类库目录
+ -cache 缓存具体实现
+ -database 数据库操作具体实现
+ -error 错误处理
+ -exception 异常处理
+ -functions 框架函数库
+ -http 请求/响应类
+ -route 路由具体实现
+ -template 模板引擎具体实现
+ -...... 实际调用的类
+ -middleware 面向控制器的中间件
+ -traits 通用trait
+ -vendor composer加载的类库
+-public 可访问公共资源
+```
+
+## 入口文件
+### 入口文件中的配置
+```
+use \top\Framework;
+
+require '../framework/Framework.php';
+
+// 可能你会使用到下面这些配置
+
+// 调试模式,缺省值:false
+// Framework::debug(true);
+// 可使用常量DEBUG取得该值
+
+// 项目目录,缺省值:./application/
+// Framework::appPath('../application/');
+// 可使用常量APP_PATH取得该值
+
+// 项目命名空间,缺省值:app
+// Framework::appNameSpace('app');
+// 可使用常量APP_NS取得该值
+
+// session保存目录,缺省值:./runtime/session/
+// Framework::sessionPath('./runtime/session/');
+// 可使用常量SESSION_PATH取得该值
+
+// 框架目录,缺省值:Framework.php的绝对路径
+// Framework::frameworkPath('../framework');
+// 可使用常量FRAMEWORK_PATH取得该值
+
+// 静态资源目录,缺省值:/resource/
+// Framework::resourcePath('/resource/');
+// 可使用常量RESOURCE取得该值
+
+// 当前入口文件默认模块,缺省值:home
+// Framework::defaultModule('home');
+
+// 路由模式,缺省值:1(pathinfo和兼容模式)
+// Framework::runType(1);
+
+Framework::appPath('../application/');
+Framework::startApp();
+```
+
## 模块
### 创建模块
1. 手动创建
@@ -107,6 +175,224 @@ public function index()
```
命名规范:before_方法名(前置)、after_方法名(后置),执行index方法之前会先执行before_index方法(如果存在),执行完index方法后会执行after_index方法(如果存在)。当前置方法return的值为空字符串、null、true时才会继续执行,否则前置方法的return等效于index方法的return。
+## 模板
+框架自带一款模板引擎,暂时命名为TOP模板引擎。此外支持扩展其他第三方模板引擎,后面会讲到,先来看看自带模板引擎的基础使用。
+### 模板继承
+模板继承通过extend标签与block标签配合使用实现。
+一个最简单的继承
+```
+// Base/layout.html(父级模板)
+
+
+
+
+
+ Title
+
+
+
+
+
+
+// Index/index.html
+
+
+
+ 内容主体
+
+```
+### 模板标签
+内置一些常用标签
+1. php
+
+php标签。此标签为闭合标签,标签内的内容将被解析为原生php代码执行。
+
+```
+
+ echo '你好';
+
+```
+
+2. if
+
+if标签。此标签为闭合标签,condition属性为if的条件,属性列表:condition。
+
+```
+
+ // do something...
+
+```
+
+3. else
+
+else标签。此标签为自闭合标签,可选属性condition,存在condition属性则被解析为elseif,属性列表:condition(可选)。
+
+```
+
+ // do something...
+
+ // do something...
+
+
+
+ // do something...
+
+ // do something...
+
+```
+
+4. volist
+
+循环标签。此标签为闭合标签,属性列表:name、id、key(可选)。
+
+```
+
+ {$item['id']}
+
+
+
+ {$i}、{$item['id']}
+
+```
+
+5. assign
+
+赋值标签,在模板中创建新的php变量。此标签为自闭合标签,属性列表:name、value。
+
+```
+
+```
+
+6. raw
+
+该标签为闭合标签。raw标签中的内容不会被编译。
+
+```
+
+
+ {$item['id']}
+
+
+```
+上例,volist标签会被原样输出。
+
+7. include
+
+在当前模板中加载其他模板文件。
+
+8. 变量、函数输出
+```
+// 变量输出
+{$username}
+
+// 调用函数,左定界符后加上:表示调用函数
+{:mb_substr($username, 0, 3, 'utf8')}
+```
+
+### 自定义标签
+新建自定义标签库类文件/application/home/taglib/Extend.php,目录及文件名称没有要求。
+#### 闭合标签
+```
+namespace app\home\taglib;
+
+class Extend
+{
+ public $tags = [
+ 'test' => ['attr' => 'start,length,id', 'close' => 1]
+ ];
+
+ public function _test($tag, $content)
+ {
+ $parse = '';
+ $parse .= $content;
+ $parse .= '';
+ return $parse;
+ }
+}
+```
+类创建完成后,到配置文件config.php的view下的tagLib中添加Extend类
+```
+'view' => [
+ 'tagLib' => [
+ \app\home\taglib\Extend::class
+ ]
+ ],
+```
+添加完成后即可在模板中使用
+```
+
+ {$test}
+
+```
+#### 自闭合标签
+添加一个描述
+```
+'say' => ['attr' => 'what', 'close' => 0]
+```
+新建_say方法
+```
+public function _say($tag)
+{
+ return "";
+}
+```
+模板调用
+```
+
+```
+
+### 模板缓存
+#### 关于模板缓存的实现
+在渲染模板后,可选择将渲染结果缓存下来(文件缓存)。在框架调用控制器之前有面向控制器的前置操作,在此会判断是否存在模板缓存文件,如果存在并且有效,则会直接使用缓存文件。否则,将会重新渲染模板。
+#### 如何使用模板缓存
+1. 在view方法中使用。第三个参数为缓存控制,传入的参数为true时使用配置文件中设置的全局缓存时间,传入数字则表示当前模板的缓存时间(秒)
+```
+return $this->view('Index/index', [
+ 'data' => $data
+], 30);
+```
+2. 直接在控制器中调用cache方法。参数作用参照view方法。
+```
+$this->cache(30);
+return [
+ 'data' => $data
+];
+```
+
+### 第三方模板引擎
+文件存放位置 'framework/library/template/driver' 。必须实现TemplateIfs接口,所以需要实现以下三个方法:
+1. run
+
+返回当前类实例,做模板引擎初始化操作。
+
+2. cache
+
+设置缓存状态。
+
+3. fetch
+
+返回模板渲染后的内容。
+
+驱动类编写完成后需要以下两个步骤,方可使用(以自带模板引擎的配置为例):
+1. 配置文件中注册
+
+```
+'register' => [
+ 'Top' => \top\library\template\driver\Top::class,
+],
+```
+
+2. 模板配置中配置使用
+
+```
+'view' => [
+ 'engine' => 'Top',
+],
+```
+
## 模型
### 创建模型
一个典型的模型(Users.php)
@@ -124,7 +410,7 @@ class 模型名称 extends Model
系统会根据模型名称去绑定对应同名称的数据表,例:模型名称为Users时,则绑定名为”前缀_users“的数据表。如果模型名称为UsersInfo时,则绑定名为“前缀_users_info”的数据表。
继承自top\library\Model基础模型后,模型将拥有以下方法或属性:
-#### 方法:
+#### 方法
1. data($data = [], $notRaw = true)
获取即将操作的数据
@@ -296,7 +582,8 @@ $this->distinct('sex')->select();
```
$this->delete(function ($model) {
$model->effect('s,this');
- $model->join('left', 'score', 's')->on('s.uid = this.id');
+ $model->join('left', 'score', 's');
+ $model->on('s.uid = this.id');
$model->where(['this.id' => 3]);
});
```
@@ -354,7 +641,8 @@ $this->limit([0, 5])->select();
一般调用
```
$this->select(function ($model) {
- $model->join('left', 'score', 's')->on('s.uid = this.id');
+ $model->join('left', 'score', 's');
+ $model->on('s.uid = this.id');
});
```
同样也可以使用连贯操作
@@ -364,7 +652,7 @@ $this->select(function ($model) {
见join方法
-#### 属性:
+#### 属性
1. $table
指定当前模型的表名(优先于模型名称)
@@ -493,219 +781,8 @@ $object = model(模型);
$object = new 模型();
```
-## 模板
-框架自带一款模板引擎,暂时命名为TOP模板引擎。此外支持扩展其他第三方模板引擎,后面会讲到,先来看看自带模板引擎的基础使用。
-### 模板继承
-模板继承通过extend标签与block标签配合使用实现。
-一个最简单的继承
-```
-// Base/layout.html(父级模板)
-
-
-
-
-
- Title
-
-
-
-
-
-
-// Index/index.html
-
-
-
- 内容主体
-
-```
-### 模板标签
-内置一些常用标签
-1. php
-
-php标签。此标签为闭合标签,标签内的内容将被解析为原生php代码执行。
-
-```
-
- echo '你好';
-
-```
-
-2. if
-
-if标签。此标签为闭合标签,condition属性为if的条件,属性列表:condition。
-
-```
-
- // do something...
-
-```
-
-3. else
-
-else标签。此标签为自闭合标签,可选属性condition,存在condition属性则被解析为elseif,属性列表:condition(可选)。
-
-```
-
- // do something...
-
- // do something...
-
-
-
- // do something...
-
- // do something...
-
-```
-
-4. volist
-
-循环标签。此标签为闭合标签,属性列表:name、id、key(可选)。
-
-```
-
- {$item['id']}
-
-
-
- {$i}、{$item['id']}
-
-```
-
-5. assign
-
-赋值标签,在模板中创建新的php变量。此标签为自闭合标签,属性列表:name、value。
-
-```
-
-```
-
-6. raw
-
-该标签为闭合标签。raw标签中的内容不会被编译。
-
-```
-
-
- {$item['id']}
-
-
-```
-上例,volist标签会被原样输出。
-
-7. 变量、函数输出
-```
-// 变量输出
-{$username}
-
-// 调用函数,左定界符后加上:表示调用函数
-{:mb_substr($username, 0, 3, 'utf8')}
-```
-
-### 自定义标签
-新建自定义标签库类文件/application/home/taglib/Extend.php,目录及文件名称没有要求。
-#### 闭合标签
-```
-namespace app\home\taglib;
-
-class Extend
-{
- public $tags = [
- 'test' => ['attr' => 'start,length,id', 'close' => 1]
- ];
-
- public function _test($tag, $content)
- {
- $parse = '';
- $parse .= $content;
- $parse .= '';
- return $parse;
- }
-}
-```
-类创建完成后,到配置文件config.php的view下的tagLib中添加Extend类
-```
-'view' => [
- 'tagLib' => [
- \app\home\taglib\Extend::class
- ]
- ],
-```
-添加完成后即可在模板中使用
-```
-
- {$test}
-
-```
-#### 自闭合标签
-添加一个描述
-```
-'say' => ['attr' => 'what', 'close' => 0]
-```
-新建_say方法
-```
-public function _say($tag)
-{
- return "";
-}
-```
-模板调用
-```
-
-```
-
-### 模板缓存
-#### 关于模板缓存的实现
-在渲染模板后,可选择将渲染结果缓存下来。在框架调用控制器之前有面向控制器的前置操作,在此会判断是否存在模板缓存文件,如果存在并且有效,则会直接使用缓存文件。否则,将会重新渲染模板。
-#### 如何使用模板缓存
-1. 在view方法中使用。第三个参数为缓存控制,传入的参数为true时使用配置文件中设置的全局缓存时间,传入数字则表示当前模板的缓存时间(秒)
-```
-return $this->view('Index/index', [
- 'data' => $data
-], 30);
-```
-2. 直接在控制器中调用cache方法。参数作用参照view方法。
-```
- $this->cache(30);
-```
-
-### 第三方模板引擎
-文件存放位置 'framework/library/template/driver' 。必须实现TemplateIfs接口。存在以下方法:
-1. run
-
-返回当前类实例,做模板引擎初始化操作。
-
-2. cache
-
-设置缓存状态。
-
-3. fetch
-
-返回模板渲染后的内容。
-
-驱动类编写完成后需要以下两个步骤,方可使用(以TOP模板引擎为例):
-1. 配置文件中注册
-
-```
-'register' => [
- 'Top' => \top\library\template\driver\Top::class,
-],
-```
-
-2. 模板配置中配置使用
-
-```
-'view' => [
- 'engine' => 'Top',
-]
-```
-
## 缓存
-缓存类实现了CacheIfs接口,所以至少存在以下四个方法:
+缓存类必须实现CacheIfs接口,所以需要实现以下四个方法:
1. set
设置缓存。三个参数,前两个为必须,第三个默认为10(秒),第一个参数为准备缓存数据的key,第二个参数为缓存的具体数据(字符串、数组、对象),第三个为当前缓存的有效时间。
@@ -739,27 +816,27 @@ $cache->exists('lists');
use top\library\cache\driver\File;
$cache = File::instance();
-if (!$cache->exists('data')) {
- $data = '测试';
- $cache->set('data', $data);
+if (!$cache->exists('text')) {
+ $text = '测试';
+ $cache->set('text', $text);
}
-$data = $cache->get('data');
+$data = $cache->get('text');
```
### Redis
```
use top\library\cache\driver\Redis;
$cache = Redis::instance();
-if (!$cache->exists('data')) {
- $data = '测试';
- $cache->set('data', $data);
+if (!$cache->exists('text')) {
+ $text = '测试';
+ $cache->set('text', $text);
}
-$data = $cache->get('data');
+$data = $cache->get('text');
```
### 自定义缓存类
文件存放位置 'framework/library/cache/driver' 。必须实现CacheIfs接口,具体方法看缓存介绍。
-## 自定义路由
+## 路由
路由配置文件位于 application 下,文件名:route.php
现有News控制器中的detail方法
```
@@ -863,7 +940,7 @@ Request::instance();
request();
```
-#### 供调用的方法
+#### 提供的方法
1. isPost
判断是否是POST请求
@@ -962,6 +1039,30 @@ request()->get('id', ['type'], function ($value) {
request()->except('type')->get();
```
+### Response类
+#### 获取实例
+```
+use top\library\http\Response;
+$instance = Response::instance();
+```
+#### 设置响应头、响应内容
+```
+return $instance->header([
+ 'HTTP/1.1 200 OK'
+])->dispatch('OK');
+```
+其中,header方法接收数组或字符串的参数,参数为具体的响应头内容。dispatch方法参数为具体响应内容,为字符串。
+如果需要文件下载,例:
+```
+$filename = './demo.zip';
+$instance>header([
+ 'Content-type: application/x-zip-compressed',
+ 'Content-Disposition: attachment; filename="demo.zip"'
+]);
+readfile($filename);
+```
+使用header方法设置响应头,接下来使用readfile函数将文件内容读取到缓冲区,这样输出时将下载demo.zip文件。或者直接使用header函数设置响应头也是可行的。
+
### 面向控制器的前置、后置方法(请求拦截)
创建application/home/filter/Auth.php测试文件
```
@@ -988,4 +1089,40 @@ class Auth implements MiddlewareIfs
\app\home\filter\Auth::class
],
```
-现在,访问项目则会得到 ' 拒绝请求 ' 结果。仅当before方法return的值为true时,程序才会继续执行,否则return等效于控制器方法的return。
\ No newline at end of file
+现在,访问项目则会得到 ' 拒绝请求 ' 结果。仅当before方法return的值为true时,程序才会继续执行,否则return等效于控制器方法的return。
+
+### 配置文件
+以home模块为例,文件位置 'application/home/config/config.php'。此外还存在一个默认配置文件,文件位置 'framework/config/config.php',如果用户存在同名配置,将会执行merge操作。
+如果需要配置数据库,将如下内容添加到应用配置文件中
+```
+'db' => [
+ 'driver' => 'MySQLi',
+ 'host' => '127.0.0.1',
+ 'user' => '',
+ 'passwd' => '',
+ 'dbname' => '',
+ 'prefix' => '',
+ 'port' => 3306,
+ 'charset' => 'utf8'
+],
+```
+如果需要其他配置,请到framework/config/config.php中查看其他的配置。
+
+### Config类
+Config类用于获取、设置配置。
+#### 获取实例
+```
+use top\library\Config;
+$instance = Config::instance();
+```
+#### 添加动态配置
+```
+$instance->set('appid', '1234566');
+```
+#### 获取配置
+```
+$instance->get('appid');
+```
+
+### Composer
+框架支持使用composer,文件位置 'composer.json'。
diff --git a/framework/config/config.php b/framework/config/config.php
index 033d71b..a59f820 100644
--- a/framework/config/config.php
+++ b/framework/config/config.php
@@ -17,6 +17,7 @@ return [
'passwd' => '',
'dbname' => '',
'prefix' => '',
+ 'port' => 3306,
'charset' => 'utf8'
],
'redis' => [
diff --git a/framework/library/database/driver/MySQLi.php b/framework/library/database/driver/MySQLi.php
index 47952d2..12189ca 100644
--- a/framework/library/database/driver/MySQLi.php
+++ b/framework/library/database/driver/MySQLi.php
@@ -27,7 +27,7 @@ class MySQLi implements DatabaseIfs
*/
public function connect($config)
{
- $link = $this->link = @mysqli_connect($config['host'], $config['user'], $config['passwd'], $config['dbname']);
+ $link = $this->link = @mysqli_connect($config['host'], $config['user'], $config['passwd'], $config['dbname'], $config['port']);
if ($link === false) {
throw new DatabaseException(mysqli_connect_error());
}
diff --git a/framework/library/database/driver/ObjectForMySQL.php b/framework/library/database/driver/ObjectForMySQL.php
index 0b8a15d..ee0c00c 100644
--- a/framework/library/database/driver/ObjectForMySQL.php
+++ b/framework/library/database/driver/ObjectForMySQL.php
@@ -28,7 +28,7 @@ class ObjectForMySQL implements DatabaseIfs
*/
public function connect($config)
{
- $this->mysqli = new \mysqli($config['host'], $config['user'], $config['passwd'], $config['dbname']);
+ $this->mysqli = new \mysqli($config['host'], $config['user'], $config['passwd'], $config['dbname'], $config['port']);
$this->mysqli->query('set names ' . $config['charset']);
return $this;
}