Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
one
提交
488cdfab
O
one
项目概览
OpenDocCN
/
one
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
one
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
488cdfab
编写于
12月 15, 2018
作者:
lzc828
提交者:
GitHub
12月 15, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update README.md
上级
255b7150
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
200 addition
and
65 deletion
+200
-65
README.md
README.md
+200
-65
未找到文件。
README.md
浏览文件 @
488cdfab
# One - 一个极简的基于swoole常驻内存框架
# One - 一个极简的基于swoole常驻内存框架
> 支持在fpm下运行
## 背景
在用过
`laravel`
框架,发现它的
`路由`
和
`数据库ORM`
确实非常好用,但是整体确实还有点慢,执行到控制器大于需要耗时60ms左右。于是打算做一个拥有非常好用的路由和orm又非常简单的框架。所以你会发现one框的
`路由`
和
`ORM`
有laravel的影子。但也有一些自己的特色,例如
`ORM`
支持自动化缓存(自动化读、写、刷新)保持与数据库同步,对外使用无感知。更多功能请看文档。one框架在fpm下整体耗时在
`1ms`
左右。
## 安装&运行
## hello world
安装
```
shell
```
shell
composer create-project lizhichao/one-app app
composer create-project lizhichao/one-app app
...
@@ -10,15 +14,22 @@ cd app
...
@@ -10,15 +14,22 @@ cd app
php App/swoole.php
php App/swoole.php
```
```
测试
```
shell
curl http://127.0.0.1:8081/
```
## 主要功能
## 主要功能
-
RESTful路由
-
RESTful路由
-
中间件
-
中间件
-
WS/TCP
……任意协议路由
-
websocket/tcp/http
……任意协议路由
-
ORM模型
-
ORM模型
-
SQL日志模板
-
统一的session处理
-
MYSQL连接池
-
mysql连接池
-
REDIS连接池
-
redis连接池
-
tcp连接池
-
HTTP/TCP/WEBOSCKET/UDP服务器
-
HTTP/TCP/WEBOSCKET/UDP服务器
-
缓存
-
缓存
-
进程间内存共享
-
进程间内存共享
...
@@ -26,12 +37,6 @@ php App/swoole.php
...
@@ -26,12 +37,6 @@ php App/swoole.php
-
日志
-
日志
-
RequestId跟踪
-
RequestId跟踪
## 支持的运行环境
-
`apache/php-fpm`
的常规环境
-
基于
`swoole`
的阻塞环境
-
基于
`swoole`
的全协程环境
[
详细文档地址
](
https://www.kancloud.cn/vic-one/php-one/826876
)
[
详细文档地址
](
https://www.kancloud.cn/vic-one/php-one/826876
)
...
@@ -42,6 +47,7 @@ QQ交流群: 731475644
...
@@ -42,6 +47,7 @@ QQ交流群: 731475644
## 路由
## 路由
```
php
```
php
Router
::
get
(
'/'
,
\
App\Controllers\IndexController
::
class
.
'@index'
);
Router
::
get
(
'/'
,
\
App\Controllers\IndexController
::
class
.
'@index'
);
// 带参数路由
// 带参数路由
...
@@ -49,8 +55,21 @@ Router::get('/user/{id}', \App\Controllers\IndexController::class . '@user');
...
@@ -49,8 +55,21 @@ Router::get('/user/{id}', \App\Controllers\IndexController::class . '@user');
// 路由分组
// 路由分组
Router
::
group
([
'namespace'
=>
'App\\Test\\WebSocket'
],
function
(){
Router
::
group
([
'namespace'
=>
'App\\Test\\WebSocket'
],
function
(){
Router
::
set
(
'ws'
,
'/a'
,
'TestController@abc'
);
// websocket 路由
// websocket 路由
Router
::
set
(
'ws'
,
'/b'
,
'TestController@bbb'
);
// websocket 路由
Router
::
set
(
'ws'
,
'/a'
,
'TestController@abc'
);
Router
::
set
(
'ws'
,
'/b'
,
'TestController@bbb'
);
});
// 中间件
Router
::
group
([
'middle'
=>
[
\
App\Test\MixPro\TestMiddle
::
class
.
'@checkSession'
]
],
function
()
{
Router
::
get
(
'/mix/ws'
,
HttpController
::
class
.
'@ws'
);
Router
::
get
(
'/mix/http'
,
HttpController
::
class
.
'@http'
);
Router
::
post
(
'/mix/http/loop'
,
HttpController
::
class
.
'@httpLoop'
);
Router
::
post
(
'/mix/http/send'
,
HttpController
::
class
.
'@httpSend'
);
});
});
```
```
...
@@ -63,103 +82,219 @@ namespace App\Model;
...
@@ -63,103 +82,219 @@ namespace App\Model;
use
One\Database\Mysql\Model
;
use
One\Database\Mysql\Model
;
// 模型里面不需要指定主键,框架会缓存数据库结构
// 自动匹配主键,自动过滤非表结构里的字段
class
User
extends
Model
class
User
extends
Model
{
{
// 定义模型对应的表名
CONST
TABLE
=
'users'
;
CONST
TABLE
=
'users'
;
// 定义关系
public
function
articles
()
public
function
articles
()
{
{
return
$this
->
hasMany
(
'id'
,
Article
::
class
,
'user_id'
);
return
$this
->
hasMany
(
'id'
,
Article
::
class
,
'user_id'
);
}
}
// 定义事件
// 是否开启自动化缓存
// ……
}
}
```
```
### 使用
### 使用
在
fpm下数据库连接为单列,
在
`fpm`
下数据库连接为单列,
在
swoole
模式下数据库连接自动切换为连接池
在
`swoole`
模式下数据库连接自动切换为连接池
```
php
```
php
// 查询一条记录
// 查询一条记录
User
::
find
(
1
);
$user
=
User
::
find
(
1
);
// 关联查询
// 关联查询
User
::
whereIn
(
'id'
,[
1
,
2
,
3
])
->
with
(
'articles'
)
->
findAll
();
$user_list
=
User
::
whereIn
(
'id'
,[
1
,
2
,
3
])
->
with
(
'articles'
)
->
findAll
();
// 更新
// 更新
user
::
where
(
'id'
,
1
)
->
update
([
'name'
=>
'aaa'
]);
$r
=
$user
->
update
([
'name'
=>
'aaa'
]);
// 或者
```
$r
=
user
::
where
(
'id'
,
1
)
->
update
([
'name'
=>
'aaa'
]);
// $r 为影响记录数量
## 日志
```
php
Log
::
debug
(
'abc'
);
Log
::
debug
([
'12,312'
]);
// 等级|时间|requestId|文件路径:行号|内容
// DEBUG|2018-11-23 15:01:26|WelxrVb5UEoFaDrQ59XnQ|/Controllers/IndexController.php:12|abc
// DEBUG|2018-11-23 15:01:26|WelxrVb5UEoFaDrQ59XnQ|/Controllers/IndexController.php:13|["12,312"]
```
```
## 缓存
## 缓存
```
php
```
php
Cache
::
set
(
'a'
,
1
);
// 设置缓存
Cache
::
set
(
'ccc'
,
1
);
//
ccc 在 tag1标签下
//
获取
Cache
::
set
(
'ccc'
,
3
,[
'tag1'
]
);
Cache
::
get
(
'ccc'
);
// 刷新 tag1 下的所有缓存
// 或者 缓存ccc 过期10s 在tag1下面
Cache
::
flush
(
'tag1'
);
Cache
::
get
(
'ccc'
,
function
(){
```
return
'缓存的信息'
;
},
10
,[
'tag1'
]);
## session
// 刷新tag1下的所有缓存
```
Cache
::
flush
(
'tag1'
);
$this->session()->get('aaa');
$this->session()->set('aaa',123);
```
```
##
添加一个webSocket服务监听
##
HTTP/TCP/WEBOSCKET/UDP服务器
需要开启什么事件就 重写父类相应事件
启动一个websocket服务器,
添加http服务监听,
添加tcp服务监听
```
php
```
php
[
[
'port'
=>
8082
,
// 主服务器
'action'
=>
\
App\Server\AppWsServer
::
class
,
//类名 作为server自带继承 WsServer ;作为监听添加继承 \One\Swoole\Listener\Ws
'server'
=>
[
'type'
=>
SWOOLE_SOCK_TCP
,
'server_type'
=>
\
One\Swoole\OneServer
::
SWOOLE_WEBSOCKET_SERVER
,
'ip'
=>
'0.0.0.0'
,
'port'
=>
8082
,
'set'
=>
[
// 事件回调
'open_http_protocol'
=>
false
,
'action'
=>
\
One\Swoole\Server\WsServer
::
class
,
'open_websocket_protocol'
=>
true
'mode'
=>
SWOOLE_PROCESS
,
'sock_type'
=>
SWOOLE_SOCK_TCP
,
'ip'
=>
'0.0.0.0'
,
// swoole 服务器设置参数
'set'
=>
[
'worker_num'
=>
5
]
],
// 添加监听
'add_listener'
=>
[
[
'port'
=>
8081
,
// 事件回调
'action'
=>
\
App\Server\AppHttpPort
::
class
,
'type'
=>
SWOOLE_SOCK_TCP
,
'ip'
=>
'0.0.0.0'
,
// 给监听设置参数
'set'
=>
[
'open_http_protocol'
=>
true
,
'open_websocket_protocol'
=>
false
]
],
[
'port'
=>
8083
,
// 打包 解包协议
'pack_protocol'
=>
\
One\Protocol\Text
::
class
,
// 事件回调
'action'
=>
\
App\Test\MixPro\TcpPort
::
class
,
'type'
=>
SWOOLE_SOCK_TCP
,
'ip'
=>
'0.0.0.0'
,
// 给监听设置参数
'set'
=>
[
'open_http_protocol'
=>
false
,
'open_websocket_protocol'
=>
false
]
]
]
]
]
];
```
## RPC
### 服务端
例如有个类
`Abc`
```
php
class
Abc
{
private
$a
;
// 初始值
public
function
__construct
(
$a
=
0
)
{
$this
->
a
=
$a
;
}
// 加法
public
function
add
(
$a
,
$b
)
{
return
$this
->
a
+
$a
+
$b
;
}
public
function
time
()
{
return
date
(
'Y-m-d H:i:s'
);
}
// 重新设初始值
public
function
setA
(
$a
)
{
$this
->
a
=
$a
;
return
$this
;
}
}
```
```
把
`Abc`
添加到rpc服务
## 添加一个TCP服务监听
```
php
需要开启什么事件就 重写父类相应事件
// 添加Abc到rpc服务
RpcServer
::
add
(
Abc
::
class
);
// 如果你不希望把Abc下的所有方法都添加到rpc服务,也可以指定添加。未指定的方法客户端无法调用.
//RpcServer::add(Abc::class,'add');
// 分组添加
//RpcServer::group([
// // 中间件 在这里可以做 权限验证 数据加解密 等等
// 'middle' => [
// TestMiddle::class . '@aa'
// ],
// // 缓存 如果设置了 当以同样的参数调用时 会返回缓存信息 不会真正调用 单位秒
// 'cache' => 10
//], function () {
// RpcServer::add(Abc::class);
// RpcServer::add(User::class);
//});
```
### 客户端调用
为了方便调用我们建立一个映射类(one框架可自动生成)
```
php
```
php
class
ClientAbc
extends
RpcClientHttp
{
[
// rpc服务器地址
'port'
=>
8083
,
protected
$_rpc_server
=
'http://127.0.0.1:8081/'
;
'protocol'
=>
\
One\Protocol\Text
::
class
,
// 协议
'action'
=>
\
App\Test\MixPro\TcpPort
::
class
,
//类名 作为server自带继承 TcpServer ;作为监听添加继承 \One\Swoole\Listener\Tcp
'type'
=>
SWOOLE_SOCK_TCP
,
'ip'
=>
'0.0.0.0'
,
'set'
=>
[
'open_http_protocol'
=>
false
,
'open_websocket_protocol'
=>
false
]
]
// 远程的类 不设置默认为当前类名
protected
$_remote_class_name
=
'Abc'
;
}
```
```
调用rpc服务器的方法, 和调用本项目的方法一样的。你可以想象这个方法就在你的项目里面。
[
详细文档地址
](
https://www.kancloud.cn/vic-one/php-one/826876
)
```
php
$abc
=
new
ClientAbc
(
5
);
[
使用列子-DEMO
](
https://github.com/lizhichao/one-demo
)
// $res === 10
$res
=
$abc
->
add
(
2
,
3
);
QQ交流群: 731475644
// $res === 105
$res
=
$abc
->
setA
(
100
)
->
add
(
2
,
3
);
```
上面是通过http协议调用的。你也可以通过其他协议调用。例如Tpc协议
```
php
class
ClientAbc
extends
RpcClientTcp
{
// rpc服务器地址
protected
$_rpc_server
=
'tcp://127.0.0.1:8081/'
;
// 远程的类 不设置默认为当前类名
protected
$_remote_class_name
=
'Abc'
;
}
```
其中类
`RpcClientHttp`
,
`RpcClientTcp`
在框架里。
你可以复制到任何其他地市使用。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录