PHP版后端API开发
开发必备
- 在进行开发之前,需要搭建好项目的运行环境。具体可查看“教程”-》“环境搭建”-》“软件安装”-》“php环境安装”
- 需掌握一定的 PHP 及 ThinkPHP6 使用技能,当然你也可以根据此处的介绍及后端API文档,使用其它语言(如Java、Python、C#等)编写后端API。
- 创建VueCMF后端API项目。具体可查看“教程”-》“安装运行”-》“安装vuecmf后端”-》“PHP语言版本”
一切开发相关的都准备好了之后,就可以开始使用IDE工具(如vscode、phpstorm等)编写代码了。接下来开始后端API代码部分介绍及如何在此基础上进行开发。
目录结构
先从代码的目录结构开始,打开你的VueCMF后端API项目,你看到的项目目录结构应该是下面的形式。如下
├─app 应用目录
│ ├─controller 控制器目录
│ ├─vuecmf vuecmf应用目录
│ ├─ ... 更多控制器基类、服务基类等文件
│ │
│ ├─common.php 公共函数文件
│ └─event.php 事件定义文件
│
├─config 配置目录
│ ├─app.php 应用配置
│ ├─cache.php 缓存配置
│ ├─console.php 控制台配置
│ ├─cookie.php Cookie配置
│ ├─database.php 数据库配置
│ ├─filesystem.php 文件磁盘配置
│ ├─lang.php 多语言配置
│ ├─log.php 日志配置
│ ├─middleware.php 中间件配置
│ ├─route.php URL和路由配置
│ ├─session.php Session配置
│ ├─tauthz.php tauthz权限存储配置
│ ├─tauthz-rbac-model.conf tauthz RBAC配置
│ ├─trace.php Trace配置
│ └─view.php 视图配置
│
├─database 项目数据初始化的定义文件存放目录
├─view 视图目录
├─route 路由定义目录
│ ├─route.php 路由定义文件
│ └─ ...
│
├─public WEB目录(对外访问目录)
│ ├─index.php 入口文件
│ ├─router.php 快速测试文件
│ └─.htaccess 用于apache的重写
│
├─extend 扩展类库目录
├─runtime 应用的运行时目录(可写,可定制)
├─vendor Composer类库目录
│ ├─vuecmf VueCMF框架核心代码文件目录
│ │ └─framework
│ │ ├─config tauthz权限配置文件存放目录
│ │ ├─database 项目数据初始化的定义文件存放目录
│ │ ├─src
│ │ │ ├─command 命令行执行命令定义文件目录
│ │ │ ├─controller 控制器文件存放目录
│ │ │ ├─make 执行生成模型类文件相关功能的代码文件存放目录
│ │ │ ├─middleware 中间件文件存放目录
│ │ │ ├─model 模型文件存放目录
│ │ │ ├─subscribe 事件文件存放目录
│ │ │ ├─common.php 公共函数文件
│ │ │ ├─ConstConf.php 常量定义文件
│ │ │ ├─event.php 事件配置文件
│ │ │ ├─middleware.php 中间件配置文件
│ │ │ └─VuecmfService.php 服务配置文件
│ │ │
│ │ ├─.gitignore git忽略文件
│ │ ├─composer.json composer定义文件
│ │ ├─LICENSE 授权协议
│ │ └─README.md 使用说明文档
│ │
│ ├─... 更多其它依赖扩展包
│
├─.env 数据库连接配置等信息文件
├─.example.env 环境变量示例文件
├─composer.json composer 定义文件
├─LICENSE 授权协议
├─LICENSE.txt 授权说明文件
├─README.md 使用说明文档
├─think 命令行入口文件
代码架构
介绍完VueCMF后端API的目录结构,下面就说说代码是如何组织的。主要由模型层、事件层、门面及中间件构成。下面就一一展开介绍。
模型层
框架的模型层代码文件存放在vendor/vuecmf/framework/src/model目录下,其作用是与数据库交互并封装成方法供事件层调用。主要有以下模型文件
- Base.php 基础模型:主要封装了一些公共方法,供其它模型继承调用。
- Admin.php 管理员模型:主要包含管理员数据的增、删、改查及是否登录方法。
- FieldOption.php 字段选项模型:主要包含字段选项的增、删、改查及获取模型字段的选项值列表方法。
- GrantAuth.php 权限管理模型:主要包含增删用户角色、给角色分配用户、增删(用户或角色)权限、获取(用户或角色)权限ID列表、获取角色下所有用户及获取用户下所有角色方法。
- Menu.php 菜单模型:主要包含菜单的增、删、改查及获取导航菜单列表方法
- ModelAction.php 模型动作:主要包含模型动作的增、删、改查、获取所有指定的API映射列表、根据动作ID获取所属模型ID方法。
- ModelConfig.php 模型配置:主要包含模型配置的增、删、改查、获取指定模型的配置信息、根据模型ID获取对应表名、根据模型ID获取对应模型名称及根据模型ID获取对应模型实例方法。
- ModelField.php 模型字段:主要包含模型字段的增、删、改查、获取可模糊搜索的字符串类型字段、获取指定字段的类型、获取模型字段信息方法。
- ModelForm.php 模型表单: 主要包含模型表单的增、删、改查及获取模型的表单信息方法。
- ModelFormLinkage.php 模型表单联动:主要包含模型表单联动的增、删、改查方法。
- ModelFormRules.php 模型表单验证: 主要包含模型表单验证的增、删、改查、根据模型ID获取模型表单的校验规则、获取模型表单的数据验证规则方法。
- ModelIndex.php 模型索引:主要包含模型索引的增、删、改查及获取模型的唯一索引字段方法。
- ModelRelation.php 模型关联: 主要包含模型关联的增、删、改查、获取关联字段信息、获取关联下拉选项列表及获取联动关联字段信息方法。
- Roles.php 角色模型:主要包含角色模型的增、删、改查方法。
以上是框架的所有模型介绍。当在后台“模型配置”列表中创建一个模型后,系统会自动在项目的app/vuecmf目录下创建一个model目录并生成一个对应的模型类文件。例如创建一个相册模型(photo)生成的模型文件内容如下
<?php
declare (strict_types = 1);
namespace app\vuecmf\model;
/**
* 相册管理模型
* Class Photo
* @package app\vuecmf\model
*/
class Photo extends Base
{
}
现在可以编辑此模型文件,在里面加上批量删除(batchDel)方法,如下
<?php
declare (strict_types = 1);
namespace app\vuecmf\model;
/**
* 相册管理模型
* Class Photo
* @package app\vuecmf\model
*/
class Photo extends Base
{
/**
* 批量删除
* @param array $id_list id 列表
* @return bool
*/
public function batchDel(array $id_list): bool
{
if(empty($id_list)) return false;
$this->whereIn('id', $id_list)->delete();
return true;
}
}
要想在其它类中不用new一个模型类,能不能像访问类的静态方法一样使用的话呢?那么接下来,门面就是解决这个问题的
门面
框架的门面代码文件存放在vendor/vuecmf/framework/src/model/facade目录下,其作用是将模型类中的方法可以转成访问类的静态方法的形式。当前已经定义好的门面类文件如下
- Admin.php 管理员模型的门面:转换可以静态访问的方法(判断是否已登录)
- FieldOption.php 字段选项模型的门面:转换可以静态访问的方法(获取模型的表单信息)
- GrantAuth.php 权限管理模型的门面:转换可以静态访问的方法(添加/删除用户角色、添加/删除(用户或角色)权限、为角色分配/清除用户、获取(用户或角色)所有权限ID列表、获取角色下所有用户名称、获取用户下所有角色名称)
- Menu.php 菜单模型的门面:转换可以静态访问的方法(获取导航菜单、获取下拉菜单列表)
- ModelAction.php 模型动作的门面:转换可以静态访问的方法(获取所有指定的API映射列表、根据动作ID获取所属模型ID)
- ModelConfig.php 模型配置的门面:转换可以静态访问的方法(根据模型ID获取对应表名、根据模型ID获取对应模型名称、根据模型ID获取对应模型实例、获取指定模型的配置信息)
- ModelField.php 模型字段的门面:转换可以静态访问的方法(获取可模糊搜索的字符串类型字段、获取指定字段的类型、获取字段信息)
- ModelForm.php 模型表单的门面:转换可以静态访问的方法(获取模型的表单信息)
- ModelFormRules.php 模型表单验证的门面:转换可以静态访问的方法(根据模型ID获取模型表单的校验规则、获取模型表单的数据验证规则)
- ModelIndex.php 模型索引的门面:转换可以静态访问的方法(获取模型的唯一索引字段)
- ModelRelation.php 模型关联的门面:转换可以静态访问的方法(获取关联字段信息)
以上是框架所有模型门面的介绍。下面就给Photo模型加一个门面类,先在项目的app/vuecmf/model目录下创建一个facade目录,然后新建一个门面类文件(Photo.php),如下
<?php
declare (strict_types = 1);
namespace app\vuecmf\model\facade;
/**
* 相册管理模型
* Class Photo
* @package app\vuecmf\model\facade
* @method static bool batchDel(array $id_list) 批量删除
*/
class Photo
{
/**
* @return string
*/
protected static function getFacadeClass(): string
{
return 'app\vuecmf\model\Photo';
}
}
创建好门面后,接下来你就可以在事件层通过访问类的静态方法一样调用batchDel方法了。
事件层
框架的事件层代码文件存放在vendor/vuecmf/framework/src/subscribe目录下,其作用是调用模型类并封装一些事件方法供控制器层调用来实现最终的后端API接口。当前已有事件类文件如下
- BaseEvent.php 基础事件抽象类:里面包含的事件有(列表、保存、批量保存、获取详情、删除、下拉列表),供其它事件类继承。
- AdminEvent.php 管理员事件类:除了继承自基础事件抽象类中所有事件外,另增加有登录、退出、添加用户角色、删除用户角色、添加用户权限、删除用户权限、获取用户所有权限、获取所有角色、获取用户下所有角色、设置用户权限、获取用户权限列表。
- FieldOptionEvent.php 字段选项事件类:包含继承自基础事件抽象类中所有事件。
- MenuEvent.php 菜单事件类:除了继承自基础事件抽象类中所有事件外,另增加有获取导航菜单列表。
- ModelActionEvent.php 模型动作事件类:除了继承自基础事件抽象类中所有事件外,另增加有获取API映射、获取所有模型的动作列表。
- ModelConfigEvent.php 模型配置事件类:包含继承自基础事件抽象类中所有事件。
- ModelFieldEvent.php 模型字段事件类:包含继承自基础事件抽象类中所有事件。
- ModelFormEvent.php 模型表单事件类:除了继承自基础事件抽象类中所有事件外,另增加有下拉列表事件。
- ModelFormLinkageEvent.php 模型表单联动事件类:包含继承自基础事件抽象类中所有事件。
- ModelFormRulesEvent.php 模型表单验证事件类:包含继承自基础事件抽象类中所有事件。
- ModelIndexEvent.php 模型索引事件类:包含继承自基础事件抽象类中所有事件。
- ModelRelationEvent.php 模型关联事件类:包含继承自基础事件抽象类中所有事件。
- RolesEvent.php 角色事件类:除了继承自基础事件抽象类中所有事件外,另增加有为角色分配用户、清除角色下的用户、添加角色权限、删除角色权限、获取角色所有权限、获取角色下所有用户、获取所有用户。
- UploadEvent.php 上传事件类:包含接收文件并保存到服务器事件。
以上是框架所有事件的介绍。当在后台“模型配置”列表中创建一个模型后,系统会自动在项目的app/vuecmf目录下创建一个subscribe目录并生成一个对应的事件类文件。例如创建一个相册模型(photo)生成的事件类文件内容如下
<?php
declare (strict_types = 1);
namespace app\vuecmf\subscribe;
/**
* 相册管理事件
* Class PhotoEvent
* @package app\vuecmf\subscribe
*/
class PhotoEvent extends BaseEvent
{
}
现在可以编辑此事件类文件,在里面加上批量删除(batchDel)事件,如下
<?php
declare (strict_types = 1);
namespace app\vuecmf\subscribe;
use app\vuecmf\model\facade\Photo;
use think\Exception;
use think\Request;
/**
* 相册管理事件
* Class PhotoEvent
* @package app\vuecmf\subscribe
*/
class PhotoEvent extends BaseEvent
{
/**
* 批量删除
* @param Request $request
* @return bool
* @throws Exception
*/
public function onBatchDel(Request $request)
{
$data = $request->post('data',[]);
if(empty($data['id_list'])) throw new Exception('参数id_list不能为空');
$id_list = explode(',', $data['id_list']);
$res = Photo::batchDel($id_list); //Photo模型定义了门面,这里就可以通过双冒号形式调用模型的方法了
if(!$res) throw new Exception('删除失败');
return true;
}
}
事件类创建好了,接下来就是在控制器层调用了。
控制器层
框架的控制器层代码文件存放在vendor/vuecmf/framework/src/controller目录下,其作用是调用事件类并定义一些动作(即最终的后端API接口)供前端请求调用。当前已有控制器类文件如下
- Base.php 基础控制器抽象类:主要包含的动作有(列表、保存、批量保存、详情、删除、下拉列表、树形列表),供其它控制器类继承。
- Admin.php 管理员控制器类:除了继承自基础控制器的所有动作外,另增加有(登录系统、退出系统、添加用户角色、删除用户角色、添加用户权限、删除用户权限、获取用户的所有权限、获取所有角色、获取用户下所有角色、添加用户权限、获取用户权限列表)。
- Error.php 异常控制器类:统一异常处理动作。
- FieldOption.php 字段选项控制器类:包含继承自基础控制器的所有动作。
- Menu.php 菜单控制器类:除了继承自基础控制器的所有动作外,另增加有导航菜单。
- ModelAction.php 模型动作控制器类:除了继承自基础控制器的所有动作外,另增加有(获取Api映射列表、获取动作列表)。
- ModelConfig.php 模型配置控制器类:包含继承自基础控制器的所有动作。
- ModelField.php 模型字段控制器类:包含继承自基础控制器的所有动作。
- ModelForm.php 模型表单控制器类:包含继承自基础控制器的所有动作。
- ModelFormLinkage.php 模型表单联动控制器类:包含继承自基础控制器的所有动作。
- ModelFormRules.php 模型表单验证控制器类:包含继承自基础控制器的所有动作。
- ModelIndex.php 模型索引控制器类:包含继承自基础控制器的所有动作。
- ModelRelation.php 模型关联控制器类:包含继承自基础控制器的所有动作。
- Roles.php 角色控制器类:除了继承自基础控制器的所有动作外,另增加有(批量分配用户、批量删除用户、添加角色权限、删除角色权限、获取角色下所有用户、获取角色下所有权限、获取所有用户)。
- Upload.php 文件上传控制器类:包含继承自基础控制器的所有动作。
以上是框架所有控制器的介绍。当在后台“模型配置”列表中创建一个模型后,系统会自动在项目的app/vuecmf目录下创建一个controller目录并生成一个对应的控制器类文件。例如创建一个相册模型(photo)生成的控制器类文件内容如下
<?php
declare (strict_types = 1);
namespace app\vuecmf\controller;
/**
* 相册管理控制器
* Class Photo
* @package app\vuecmf\controller
*/
class Photo extends Base
{
}
现在可以编辑此控制器类文件,在里面加上批量删除(batchDel)动作,如下
<?php
declare (strict_types = 1);
namespace app\vuecmf\controller;
/**
* 相册管理控制器
* Class Photo
* @package app\vuecmf\controller
*/
class Photo extends Base
{
/**
* 批量删除
* @return \think\response\Json
*/
public function batchDel(): \think\response\Json
{
return self::common('BatchDel', '删除成功','删除失败');
}
}
注意
控制器中的公共方法common的第一个参数event_name(事件名称),是来自于subscribe目录下对应事件类文件中定义的事件方法(如PhotoEvent.php中的onBatchDel事件方法)去除开头的"on"(如BatchDel)
到目前为止,增加的“相册批量删除”后端API已开发完了,现需要将其对应模型的动作列表中。下面就将“批量删除”动作添加到先前创建的相册管理模型(photo)中,如下
在”模型配置“列表中找到”相册管理“模型所在行,点击后面的”动作“,在弹出的”设置(相册管理)动作“窗口中,点击”新增“按钮 动作添加好后,在前端部分添加的批量删除功能,现在就可以正常使用了。
后端API开发好了,VueCMF框架是如何实现其权限控制及表单校验的呢?接下来,就是中间件来解决这个问题了
中间件
框架的中间件代码文件存放在vendor/vuecmf/framework/src/middleware目录下,其作用是对所有请求进行前置拦截并进行相应的处理(如API的权限控制)。当前已有中间件类文件如下
- Auth.php 访问权限控制中间件:主要负责后端API的访问权限控制及请求参数传递。
- DataCheck.php 数据校验中间件:主要负责表单提交的数据进行验证。
以上是框架的中间件介绍。具体实现代码就不贴出来,详细的可打开项目中对应类文件查看。
若你需要创建自己的中间件实现一些功能。可以在项目的app/vuecmf下创建一个middleware目录,在里面新建自己的中间件类文件,然后将其配置在app/vuecmf下的middleware.php配置文件中或具体的控制器类文件中,如下
<?php
// 这是系统自动生成的middleware定义文件
return [
// Session初始化
\think\middleware\SessionInit::class,
//在这里添加自己创建的中间件类
];
/**
* 相册管理控制器
* Class Photo
* @package app\vuecmf\controller
*/
class Photo extends Base
{
//配置访问权限和表单数据校验中间件
protected $middleware = [
DataCheck::class => ['only' => ['save','saveAll']],
//在这里添加自己创建的中间件类
];
//......后面代码省略
}
现在后端API已全部开发完了,接下来就调试测试了
调试
代码都编写好了,下面就需要进行功能调试了,验证功能是否可用,有没有什么Bug。 打开API测试工具(如Postman),如下
部署
当调试没有问题,功能可以正常使用后,就可以部署到生产环境了。 详细的操作请参考:“教程”下面的 安装vuecmf后端 章节