演示说明
-
以框架衔接各技术边界, 降低成本, 提高效率
- 从研发到测试, 并行解决方案
- 上下层透明, 易于数据分布, 方便环境扩展
演示部署
-
下载演示代码 demo
解压到项目根目录 /flow 中
修改框架配置文件: 'config' => '/flow/config.php'
- 安装单点登录 sso
配置框架配置文件: 'db' 连接一个数据库
访问 /include/of/?c=of_base_sso_main 并登录 admin 123456 自动创建数据库
修改系统分页中"sso"中 "对接" 下拉为 "前后台对接", 点击保存
- 访问 /flow/index.php
用 sso 里的帐号 admin 123456 进行登录
涉及功能
- 单点登录系统(负责帐号及权限管理) sso
- htmlLoad html共享(负责静态html实现include功能) htmlLoad
- html模版引擎(负责无缝将html和php整合) htmlTpl
- 接口规则验证(负责校验数据是否符合指定规矩) data::rule
- 接口测试工具(负责接口单元测试) tool::check
- 错误日志(负责记录前后端数据库的错误)errorLog
入口讲解
/flow/index.php
<?php
/**
* 描述 : 控制层共享文件, 控制层文件与类名相同, 以$_GET['a']作为方法名(默认index)
*/
//加载核心
require dirname(dirname(__FILE__)) . '/include/of/of.php';
//已登录
if (of_base_sso_tool::check()) {
//展示首页界面
$_GET += array('c' => 'flow_ctrl_main', 'a' => 'index');
//无权访问 sso 中的权限校验, 推荐使用类似 class::action 方式设置权限键, 这样可以统一判断
of_base_sso_tool::role("{$_GET['c']}::{$_GET['a']}") || $_GET = array('c' => 'flow_ctrl_main', 'a' => 'unRole');
//未登录
} else {
//登录中
if (
isset($_GET['c']) && $_GET['c'] === 'flow_ctrl_main' &&
isset($_GET['a']) && $_GET['a'] === 'login'
) {
//启动定时器
of_base_com_timer::timer();
} else {
//展示登录界面
$_GET = array('c' => 'flow_ctrl_main', 'a' => 'door');
}
}
//调度 类名, 动作, 安全校验,允许访问的文件返回值必须与此相同,false=不通过
$result = of::dispatch($_GET['c'], $_GET['a'], true);
//控制层返回数组时, 转换为 json 结构 接口通信核心
if (is_array($result)) echo of_base_com_data::json($result);
无权访问
展示界面 flow_ctrl_main::unRole
<?php
/**
* 描述 : 无权访问界面
*/
public function unRole() {
//向视图层传入基础数据 title, info
$this->view->title = '无权访问';
$this->view->info = '您无权访问当前页面, 请联系管理员开通';
//通知模版引擎编译
$this->display('/error.html');
}
模版代码 /view/error.html
<!-- 简单说, 模版就是使用 html 方式写 php 代码 -->
<h2 class="font-bold" __html="$this->title">服务器内部错误</h2>
<div class="error-desc">
<!--<? echo $this->info; ?>-->服务器好像出错了...
<br/><a _href="/flow/" href="index-2.html" class="btn btn-primary m-t">主页</a>
</div>
登录界面
单点登录 flow_ctrl_main::door
<?php
/**
* 描述 : 显示登录界面
*/
public function door() {
//调用 html模版引擎, 编译静态页面
$this->display('/login.html');
}
登录接口 flow_ctrl_main::login
<?php
/**
* 描述 : 登录帐号
*/
public function login() {
if (isset($_POST['user']) && isset($_POST['pwd']) && isset($_POST['captcha'])) {
//验证通过
if (of_base_com_com::captcha($_POST['captcha'])) {
//校验用户名和密码 调用 sso 接口
$state = of_base_sso_tool::login(array(
'user' => &$_POST['user'],
'pwd' => &$_POST['pwd']
));
//登录成功
if ($state === true) {
echo 'done';
//登录出错
} else if ($state) {
echo $state['msg'];
//登录失败
} else {
echo '帐号密码错误';
}
//验证失败
} else {
echo '验证码错误';
}
}
}
单点退出 flow_ctrl_main::logout
<?php
/**
* 描述 : 退出帐号
*/
public function logout() {
//调用 sso 退出
of_base_sso_tool::logout();
L::header(ROOT_URL . '/flow/index.php');
}
接口演示
请求验证 flow_ctrl_main::__construct
<?php
/**
* 描述 : 请求验证, 放在构造函数中的验证可以进行单元测试
*/
public function __construct() {
//定义全局规则
$rule = array(
'getMsgs' => array(
'get' => array(
'size' => 'int'
)
)
);
L::rule($rule);
}
实现接口 flow_ctrl_main::getMsgs
<?php
/**
* 描述 : 获取消息列表
* 注明 :
* 标准响应结构 {
* "code" : 正整型, 200 成功, 400 请求参数类型校验失败,
* 3xx 半失败半成功, 且有效
* 4xx 因请求参数导致的错误
* 5xx 因内部错误导致的问题
* "data" : 可扩展的数据数据
* "info" : 字符串的响应信息
* }
*/
public function getMsgs() {
$data = array(
'list' => array(
array(
'img' => '/img/a1.jpg',
'name' => '谨斯里',
'title' => '上传了一个文件',
'time' => '2014.11.8 12:22',
'msgs' => '消息1',
), ...
)
);
return array(
'code' => 200,
'data' => &$data,
'info' => "读取成功"
);
}
数据填充 /flow/view/index.html
<div id="ibox" _style="'display: none;'" class="ibox-content">
<div name="list" class="feed-activity-list">
<div v-for="item in list" class="feed-element">
<img name="img" class="pull-left img-circle" :src="VIEW_URL + item.img" src="img/a1.jpg">
<div class="media-body ">
<small name="time" class="pull-right" v-text="item.msgs">5分钟前</small>
<strong name="name" v-text="item.name">谨斯里</strong>
<font name="title" v-text="item.title">上传了一个文件</font>
<br>
<small name="msgs" class="text-muted" v-text="item.time">2014.11.8 12:22</small>
</div>
</div>
</div>
</div>
<script>
//通过接口填充数据
$.post(ROOT_URL + '/flow/index.php?c=flow_ctrl_main&a=getMsgs&size=5', function (data) {
//标准响应结构
if (data.code === 200) {
//利用 Vue 填充数据
var app = new Vue({
el: $('#ibox').show().get(0),
data: {
list: data.data.list
}
});
}
L.open('tip')('提示消息: ' + data.info);
}, 'json');
</script>
接口测试
请求验证 flow_ctrl_main::apiTest
<?php
/**
* 描述 : 接口测试
*/
public function apiTest() {
//模拟GET, POST, COOKIE 等数据
//$_POST = array('aa' => '123');
$error = of_base_tool_test::check('flow_ctrl_main', 'getMsgs');
if ($error) {
echo '<pre>';
echo 'flow_ctrl_main::getMsgs ';
echo '<a href="?c=flow_ctrl_main&a=apiTest&size=1" style="color: red;">传入size为int的get参数会响应正确信息</a> ';
print_r($error);
echo '</pre>';
} else {
echo '无数据返回';
}
}
错误提示
- 在debug模式下,出现错误时会有醒目的信息提示
- 不管是否debug模式,都可以通过访问 框架目录/index.php?c=of_base_error_tool 来查阅以往错误的详细信息