【腾讯云的1001种玩法】CRUD生成器DBuilder介绍与腾讯云部署

第一部分 说明

1.意义

Dbuilder是基于laravel4开发的一套快速实现数据库表CRUD(增删改查)操作的工具,核心思想是做到针对数据库表的每个字段做到精确配置,通过生成字段配置并通过修改配置的方式来实现增删改查功能,无需编写数据库操作代码。

2.现状

国外有类似的CRUD生成器产品:CrudKit,CRUD-Admin-Generator,Dadabik,GroceryCrud,SximoBuilder。这些产品各有其特点,但也有一共同点:都是基于PHP进行开发(这在一定程度上决定于PHP语法的灵活性及其弱类型性)。SximoBuilder是其中的做的较好的,但也存在如下不足之处:

  • 不支持自定义表单控件;
  • 不支持多数据库;
  • 验证规则不完善,不支持异步验证;
  • 代码冗余度极大。

第二部分 DBuilder设计

模型

DBuilder有下面2个核心的构件Core CRUD 模块和GModule,GModule对Core CRUD 模块有继承依赖的关系,GModule由MVC Code和CRUD Config组成;Core CRUD模块是手工编写的代码,而GModule是DBuilder生成的代码;Core CRUD 模块实现CRUD操作,GModule实现扩展功能。下图表示了这两个构件的组成和关系

图2-1概念与构件

下面对图中设计的概念、构件、模块关系以及Build与CRUD流程做详细阐述。

1.Core CRUD 模块 Core CRUD 模块实现核心CRUD操作,一切对GModule MVC中Controller的CRUD请求,最终转交至Core CRUD 模块进行处理。Core CRUD 模块会开放一些预处理和后处理接口交由GModule实现,这些接口会在Model,Controller,View上都有体现。 Core CRUD 模块主要包括如下文件

  • app/controllers/admin/AdminController.php
  • app/models/BaseModel.php
  • app/config/crud/admin.php
  • app/views/admin/core/list.blade.php
  • app/views/admin/core/form.blade.php Core CRUD 模块读取GModule Configuration实现真正的CRUD操作。

2.GModule GModule(Generated Module)不但实现了Core CRUD Module接口(MVC代码),而且具有自己配置文件(CRUD Configuration)。每一GModule表示以一张数据库表为主表,具备CRUD功能的代码文件合集(包括对应的MVC + Configuration代码)。譬如,DBuilder生成的一个GModule, 主表为core数据源user表,名字为User,那么User GModule应包含下面代码文件:

  • controllers/UserController.php
  • models/User.php
  • views/user/_list.blade.php
  • views/user/_form.blade.php
  • views/user/view.blade.php
  • config/crud/user.php

代码文件命名取决于GModule的名字,故为保证生成的代码文件不冲突,取GModule的名字(GModule Key,GModule Name)作为GModule的唯一标识。每一个GModule的信息都被保存在数据库中。一次新建 GModule操作将会新建上述所有代码文件,更新相关文件,并插入一条GModule记录到数据库。一次更新 GModule操作将只会更新Configuration文件。 GModule 由MVC代码和CRUD Configuration代码组成,下面分别进行阐述:

  • MVC代码:用来实现扩展接口。CRUD请求应最先路由到GModule MVC的中的Controller(控制器)。并且GModule MVC 应与Core CRUD Module的MVC代码有继承关系。
  • CRUD Configuration代码:实现对GModule主表增删改查参数的配置。该文件放置在app/config/crud/目录下,以php array的格式定义。它包含对所有字段的表单,列表,视图,关系等参数的配置,以及全局的参数配置。

GModule并不表示具体某一个模块,而是代指一类模块,这种模块可以由DBuilder生成,或者由开发人员手工建立。它主要用来实现Core CRUD Module的接口,主要包括下述几部分: 1) Controller接口 假设GModule模块的 Controller为A,Core CRUD Module 的Controller为B,则A应继承自B。CRUD请求会先路由到A,而实际的处理者是B。A会实现B开放的下列接口。

  • beforeListExcuteQuery(&querier):该接口在List查询器执行查询之前调用,传递的参数为查询器引用。用来在查询之前,绑定特殊的查询参数。
  • beforeList(&data):该接口在List查询器执行之后,渲染List视图之前调用。传递的参数为视图参数引用,其中包括查询出的model集合。用来对查询的model 集合做后处理,或者对list视图绑定一些Module专有的参数。
  • beforeEditExcuteQuery(&querier):该接口在Edit请求中Model查询器执行查询之前调用,传递的是查询器引用。用来绑定查询model需要的特殊参数。
  • beforeEdit(&data):该接口在Edit中Model查询器执行之后,渲染视图之前调用,传递的是视图参数引用,其中包括查询器查询出的model。用来做渲染前的预处理。
  • afterSave(&model):该接口在Edit中,保存编辑的之后调用,传递的是保存在数据库中,最新的数据库记录持久化的model。用来对model做一些复杂的后级联处理。
  • beforeView(data): 该接口在View请求中,View 查询器查询之后调用,传递的是视图参数的引用。用来对视图显示做预处理。

2) Model 接口 GModule MVC代码中的Model也继承自BaseModel,实现 BaseModel类开放的一些接口可以完成扩展。 formatXXXAttribute():该接口用来格式化某个字段。本产品基于Laravel,其已经具备类似的接口,就是getXXXXAttribute()。但这样的接口的优先级比字段优先级高,这在特殊的情况下为开发带来了不便,所以再设计一个类似的接口,该接口的优先级低于字段本身。

3) View 接口 视图的扩展接口与前两者不同,主要体现在子视图与视图块上,也就是在Core CURD模块的视图基础上,扩展视图组件。默认Core CRUD MVC视图生成的是一个表格或者一个表单,占满页面。而View接口将提供在该表格上下左右扩展页面组件的能力。

4) Configuration 每一个GModule对应一个Configuration文件,其中包含GModule对主表各个字段的配置参数,以及布局参数。

3.模块关系 CRUD请求路由到GModule的Controller,GModule代码实现Core CRUD MVC开放的接口,而由Core CRUD Module去真正实现对数据库的CRUD操作。每一个GModule的信息应该被记录在数据库表中,以便给GModule关联菜单,控制权限,记录操作日志等等。一些主要模块之间的关系如下图所示。

图2-2模块关系

从图2-2中可以看到,由GModule管理模块根据用户配置来生成一个GModule A,当用户的CRUD请求到达GModule A时,GModule 会讲请求转交Core CRUD进行处理,Core CRUD 模块再以SQL对数据库进行CRUD操作。

4.Build 与 CRUD流程 DBuilder项目的方案,将真正的CRUD操作交给了Core CRUD Module去执行,CRUD参数由GET或者POST请求参数与GModule Configuration构成,而GModule的MVC代码只是去实现Core CRUD MVC开放的一些预处理或者后处理接口。 图2-3是DBuilder最核心的流程图,包含Module的生成和处理CRUD请求的过程,图2-4是SximoBuilder 中Module的生成和处理CRUD请求的流程图。

图2-3 DBuilder 代码生成和处理CRUD的流程

图2-4 SximoBuilder 代码生成和处理CRUD的流程

对比两者,可以看到两者的最大区别,是DBuilder复用一份CRUD代码,而不是像Sximo那样为每一个Module生成一套可以当独执行的CRUD代码。这样做的好处是提高了复用性,并通过Module CRUD MVC实现预处理/后处理接口达到扩展性的目的。

Core数据源

Core数据源是DBuilder的默认数据源,其类型为mysql,数据库名为dbuilder,,数据源信息保存在代码文件app/config/datasource.php中,文件内容如下:

<?php return array (
    'core' =>
        array (
            'driver' => 'mysql',
            'host' => 'localhost',
            'database' => 'dbuilder',
            'username' => 'root',
            'password' => 'root',
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'edit' => false,
            'port' => 3306,
        ),
        // more data source
 );

其中Core数据源有下述数据表: 1) d_menu 表:表示后台左侧树形菜单,每一个可点击跳转的菜单项必须与一个Module进行关联。

2) d_module 表:记录了module信息,每一条d_module表的记录代表了DBuilder生成的一个Module。

3) d_user 表:保存着使用后台程序的用户。

4) d_group表:表示对后台用户的分组信息。

5) d_group_access表:记录了每个GModule、不同后台用户组与各种操作权限的三维权限信息。

6) d_log表:记录了每个用户的操作日志。

数据源管理模块

DBuilder需要支持多数据源,多种类型数据库。数据源信息保存在d_database表中。考虑到数据库操作是频繁操作,如果将数据源信息保存在数据库中,则每次数据库操作将多一次数据源查询操作,这样做浪费性能。那么DBuilder不应该把数据源信息保存在数据库中,而应该保存在代码文件中。数据源管理的信息包括数据源名称(数据源的唯一标识,DBuilder默认的数据源名为core)、数据库类型、地址、端口、数据库名、用户名、密码等等信息。因为数据源管理模块并不对表进行增删改查操作,所以数据源管理模块并不是一个GModule模块。该模块的代码完全手工编写。

GModule 管理模块

DBuilder将以基于名字为“Module”的GModule作为生成GModule的用户接口,该模块称作GModule管理模块,换言之GModule管理模块本身就是一个GModule,该GModule的主表即是core数据源中保存GModule信息的数据库表,改GModule的名字为“Module”。GModule 管理模块包含创建,更新和删除GModule 的所有代码文件以及数据库记录。GModule的新建和删除需要更新全局的GModule路由。

1.GModule 路由 GModule路由定义在一个独立的代码文件中,为一个以GModule名字进行减号分词并全部小写的字符串为键(譬如:GModule名字为OrderItem,则键值为order-item)、以Module中Controller类的类名为值的map字典,GModule路由是全局的。

2.GModule 新建&更新 新建GModule将在数据库中生成一条记录、生成所有的module文件、并更新路由。更新操作只修改配置文件。新建与更新都使用相同的编辑视图,此编辑视图是对GModule Configuration的图形化配置界面。

3.GModule 删除 GModule删除将删除所有的GModule MVC代码,删除GModule Configuration代码,删除数据库表记录,并更新GModule路由。

Core CRUD 模块

Core CRUD 模块是DBuilder处理CRUD请求的实际处理者,它由下述几部分组成:

1.参数解析初始化 初始化Model,实例化一个Module的Model对象作为初始化查询器。加载Module Configuration,对未设置的值进行设置默认值,对参数进行汇聚。

2.表单Form 主要包括新建和更新功能。根据GModule主表主键primaryKey是否设置判断是新建还是更新操作。下图是Form模块的流程

图2-5 Form执行流程

Form 分两部分,第一部分渲染Form页面给用户填写。第二部分为Form保存。 渲染Form页面需要考虑的有Form控件和有外键关系的字段要怎么处理。Form控件需要支持类型包括text、text_date、text_datetime、textarea、select、radio、checkbox、file、hidden、address以及custom,自定义控件应该继承FormControl类,自定义控件的渲染由控件的render方法完成。Form渲染需要判断有关系的字段做辅助加载。比如对post(文章)表进行编辑,post表有一个字段为category_id,表示文章的栏目ID,对应category(栏目)表的id字段。这时需要对category_id使用select,radio,checkbox控件进行加载,方便用户输入。比如使用select控件,那么应该将category.id作为option的value,将category.name作为option中的text。这样做也是为了方便用户输入。此步骤与List中搜索时有共性,因此代码可复用。 Form 保存需要考虑一些自定义控件的保存,自定义控件的数保存由自定义控件类的onSave方法完成。Form 保存还需要考虑关系的保存,默认应该级联更新附属表。Form 表单在用户输入完成点击保存之后,要分下面几步:

  • 根据字段配置的验证规则进行验证;
  • 应判断Module Configuration 中的relation进行分析,进行必要的级联操作;
  • 并要调用自定义控件的onSave方法;
  • 最后才应更新或新建主表数据;
  • 跳转:更新或新建成功跳转至List,失败跳转至Form。
  • Form 还需要开放对应的预处理和后处理接口。

3.列表List(Table) List是一个分页Table,按照Module Configuration 中的字段配置显示分页数据。支持列表搜索,排序,勾选删除,导出等功能;

  • 分页展现数据以InitQuerier模块得到的Model作为查询器,结合分页,查询出基本的数据列表。分页类型为全页刷新类型(非异步分页);
  • List搜索:支持在Module Configuration中定义了search不等于false的字段作为搜索条件。搜索关系为逻辑与的关系。并反映在GET参数上。搜索输入控件根据字段的form type来定。在Form 中定义为select,radio,checkbox控件的字段,在List中都将使用select控件作为输入控件;
  • List 排序:以在Module Configuration中定义了form.sort 不等于 false的字段作为可排序字段。排序只支持按单一字段排序,降序方式含升序和降序;
  • List 多选操作主要支持多选删除,多选复制操作,任何删除操作都需确认;
  • List 数据每行记录的支持的操作按Module Configuration中的配置给出,默认支持编辑,删除,查看三项操作;
  • List 也要开放预处理/后处理接口给Module CRUD MVC。

4.查看View View 暂时以Form为基础,提供预处理后处理接口,但不允许编辑。

第三部分 DBuilder实现

目录结构

代码按照前段资源、MVC、Configuration、Library等概念进行了分目录存放。下面表格中给出了主要目录的说明:

GModule 配置文件

GModule配置文件定义了GModule的参数,该文件保存在app/config/crud/下,是以GModule Name进行蛇形分词得到的字符串命名的php文件(譬如:一GModule的名字为OrderItem,则GModule配置文件为order_item.php)。配置参数以数组格式返回。 考虑到PHP数组在表格中呈现的美观性,对参数以配置中的Key=>Value形式,以点分形式Key.Value表示。

表3-4中每个字段的表单配置说明如下表所示:

表3-5中每个字段的列表配置说明如下表所示:

表3-6中每个字段的关系配置说明如下表所示:

CoreCRUD 模块实现

CoreCRUD模块涉及的代码文件极其作用如下说明。

  • app/controllers/admin/AdminController.php:CoreCRUD模块的控制器,是CRUD操作核心的逻辑代码。主要分析请求参数和Module参数,调用Model层,渲染视图层,实现List呈现、List搜索排序、Form呈现、Form保存等功能;
  • app/models/BaseModel.php:CoreCRUD模块中的模型,是ModuleCRUD模块中模型的基类。未与表格关联。定义了一些公共的Model默认属性,以及一些静态的数据库操作方法,比如拉取数据库表字段列表;
  • app/config/crud/admin.php:CoreCRUD模块中的默认crud参数配置文件,但ModuleCRUD模块中的配置文件未定义某些参数时,将使用admin.php中的默认参数;
  • app/views/admin/core/list.blade.php:CoreCRUD模块中的列表视图文件,用来呈现数据列表;
  • app/views/admin/core/form.blade.php:CoreCRUD模块中的数据记录编辑视图文件,用来呈现数据编辑的表单。

GModule 管理模块实现

GModule是一类由DBuilder生成的模块,它有一组模板定义在app/template目录下:

  • app/template/_form.tpl
  • app/template/_list.tpl
  • app/template/controller.tpl
  • app/template/model.tpl

前面设计中指出,GModule管理模块本身是一个名为“Module”,主表为d_module,且手工建立的GModule,故其代码组成也是符合GModule规范的,笔者编写的代码主要为扩展代码。GModule管理模块对应了下述代码文件:

  • app/controllers/admin/ModuleController.php:控制器(Controller)代码,其实现CoreCRUD模块的接口,以及扩展的url接口;
  • app/models/Module.php:GModule管理模块的模型;
  • app/views/admin/module/_form.blade.php: FORM视图代码,其在原有的CoreCRUD 模块的FORM表单下部,扩展了一组Tab,其中第一个Tab中显示了所有字段的详细配置,通过以上扩展就能实现在CoreCRUD生成的Form表单页面中对GModule进行配置;
  • app/views/admin/module/_list.blade.php: LIST视图代码;
  • app/views/admin/module/fields_config.blade.php:字段配置表格视图代码;
  • app/views/admin/module/list_item_links.blade.php:扩展链接视图代码;
  • app/config/crud/module.php:GModule Configuration文件。

第四部分 部署到腾讯云

环境要求

本文将基于LNMP(Linux+Nginx+MySQL+PHP)环境进行部署,详细部署环境要求:

  • PHP Version > 5.4
  • MCrypt PHP 必须安装
  • OpenSSL 必须安装
  • MySQL Version > 5.4
  • Nginx、Apache等服务器

腾讯云主机

部署机器可以在腾讯云上购买,在腾讯云首页->云产品->基础产品->计算->云服务器中可以购买机器,另外可以单独购买数据库机器,这里讲数据库与web服务器部署在同一台机器上

图4-1 腾讯云主机

购买完成之后,可以在腾讯云控制台中看到购买的机器,复制公网IP

图4-2 腾讯云控制台

腾讯云支持Public Key登录和账密登录,这里用xshell 以账号密码的形式登录

图4-3 Xshell配置1

图4-4 Xshell配置2

登录上机器之后,我们需搭建web运行环境,在此为测试demo,所以将http服务器软件,数据库软件等都装在同一台机器。安装环境可以使用自动话的脚本安装,在腾讯云->服务市场->镜像服务->全能环境 或者 腾讯云->服务市场->运维服务->环境配置中,都可以找到很多自动化安装LNMP(Linux + Nginx+MySQL+PHP)、LNMT(Linux+Nginx+MySQL+Tomcat)等等的基础运行环境 。比如LNMTXAMPP 在此我使用一键安装包,安装步骤参考地址,可以看到,腾讯云机器的下载速度是非常快的

部署配置

安装完之后,参考lnmp.org的配置我们就可以开始配置了 首先,需要将DBuilder放置到Nginx的Default Server或者Vhost中,这里以Default Server为例。本文中DBuilder的根目录为 /data/release/dbuilder/ 编辑nginx.conf文件,修改server节点:

server
{
    listen 80 default_server;
    #listen [::]:80 default_server ipv6only=on;
    #server_name dbuilder.org;
    index index.html index.htm index.php;
    root  /data/release/dbuilder;

    #error_page   404   /404.html;
    include enable-php.conf;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ [^/]\.php(/|$)
    {
            # comment try_files $uri =404; to enable pathinfo
            try_files $uri =404;
            fastcgi_pass  unix:/tmp/php-cgi.sock;
            #fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi.conf;
            #include pathinfo.conf;
    }

    location /nginx_status
    {
        stub_status on;
        access_log   off;
    }

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
    {
        expires      30d;
    }

    location ~ .*\.(js|css)?$
    {
        expires      12h;
    }

    location ~ /\.
    {
        deny all;
    }

    access_log  /home/wwwlogs/access.log  access;
}

修改DBuilder项目文件所属用户,保证nginx http进程对文件有读权限,本文部署环境中,nginx http进程为www用户进程;同时需要给部分DBuilder目录完全的写入权限,执行下列命令:

cd /data/release
chown –R www dbuilder
chgrp –R www dbuilder
cd dbuilder
chmod –R 777 app/storage
chmod -R 665 app/controllers/admin app/config/crud app/models/ app/views

建立数据库,在mysql中创建名为dbuilder的数据库,并source Dbuilder根目录下的dbuilder.sql,具体执行如下命令

# 首先进入msyql
mysql –uroot –pyour_root_password
# 进入mysql之后
create database dbuilder default char set utf8;
use dbuilder;
source /data/release/dbuilder/dbuilder.sql;

至此DBuilder部署完成,通过浏览器访问页面 (hostname为主机域名或ip地址)即可以访问到DBuilder。

第五部分 案例

设定:在不编写代码的基础上,以DBuilder生成一个简单可用的博客后台,博客后台有post表和category表,位于core数据源。

CREATE TABLE post
(
    id INT(11) PRIMARY KEY NOT NULL,
    category_id INT(11) NOT NULL,
    title VARCHAR(64) NOT NULL,
    short VARCHAR(256) NOT NULL,
    content TEXT NOT NULL,
    view_ct INT(11) DEFAULT '0' NOT NULL,
    created_at TIMESTAMP DEFAULT 'CURRENT_TIMESTAMP' NOT NULL,
    updated_at TIMESTAMP DEFAULT '0000-00-00 00:00:00' NOT NULL
) DEFAULT CHAR SET utf8;

CREATE TABLE category
(
    id INT(11) PRIMARY KEY NOT NULL,
    title VARCHAR(32) NOT NULL,
    level INT(11),
    weight INT(11) DEFAULT '0' NOT NULL COMMENT '排序字段',
    parent_id INT(11),
    post_ct INT(11) DEFAULT '0' NOT NULL,
) DEFAULT CHAR SET utf8;

新建GModule

准备好数据库表即可新建GModule,下面新建名为“Post”的GModule。进入GModule管理->新建界面,按图填写保存。

图5-1 新建GModule页面

编辑新建的Post GModule,可以看到在下部多出一个含有表格的tab。

图5-2 GModule Configuration字段配置页面

现在对于post表的所有字段都是默认配置,分别查看List和Form,可以看到List和Form都能正常读取数据库数据。

图5-3 GMoudle 列表页面

图5-4 GModule表单页面

上面两图呈现的List和Form并不具有可用性,因此需要对字段做配置。

GModule配置

首先修改字段的中文名、是否包含在form、是否包含在List等属性。

图5-5 GModule Configuration字段配置页面

保存之后,再次刷新Post列表和Form。对比图5-3、图5-4发现内容发生了变化

图5-6 GModule列表页面

图5-7 GModule表单页面

下面对每个字段做更详细的配置以得到更符合我们需求的页面,修改控件类型:short(摘要)字段为textarea(多行文本)类型,content(正文)字段为wysiwyg(富文本)类型,category_id字段为select(下拉列表)类型,updated_at(修改时间)为date(日期)类型。修改category_id(栏目外键)的关系为所属关系,并填写如下:

图5-8 GModule 字段详细配置表单

修改short(摘要)字段、title(标题)字段为不可排序与like模糊搜索,修改updated_at搜索方式为“>=”搜索

List&Form效果

刷新Post列表,可看到如下两个控件:date和select控件。

图5-9 GModule 列表搜索日期与下拉列表控件

输入搜索条件为修改日期:2016-03-03、栏目:C++、摘要:收到。结果按阅读次数排序。得到下面的列表结果。

图5-10 GModule 列表搜索与排序

点击其中一条记录进行编辑,测试Form功能。

图5-11 GModule编辑表单

修改之后点击保存也是正常可用的。 整个配置过程,只需几分钟,但却实现了上述功能。 工具演示地址

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

吕亚辉的专栏

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Core Net

懒人小技巧, Toad 常用偷懒方法

2969
来自专栏C/C++基础

Linux命令(29)——ls命令

ls命令用来显示目录内容,在Linux中是使用率较高的命令。ls命令的输出信息可以进行彩色加亮显示,以分区不同类型的文件。

531
来自专栏别先生

Hadoop Shell命令(基于linux操作系统上传下载文件到hdfs文件系统基本命令学习)

Apache-->hadoop的官网文档命令学习:http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_shell.html...

2007
来自专栏开发与安全

linux系统编程之文件与I/O(三):目录的操作

一、目录的访问 功能说明:打开一个目录 原型:DIR*  opendir(char *pathname); 返回值: 打开成功,返回一个目录指针 打开...

1595
来自专栏闵开慧

Hadoop FS Shell命令大全

    调用文件系统(FS)Shell命令应使用 bin/hadoop fs <args>的形式。 所有的的FS shell命令使用URI路径作为参数。URI格...

3559
来自专栏遊俠扎彪

如何解决MySQL中文乱码及插入中文信息错误的问题

从前和最近,帮人做点东西的时候,都遇到过MySQL与中文不兼容的问题,从前都是凭借尝试与运气解决问题这次好好总结一下:

1836
来自专栏木子昭的博客

效率至上的nodejs 手动实现服务器

nodejs的语法和浏览器js的语法非常接近, 安装好node后, 可以写个正则, 测试一下环境是否安装成功, 通过atom的script插...

661
来自专栏TechBox

iOS经典错误Undefined symbols for architecture XXX:

1882
来自专栏C/C++基础

Linux命令(20)——cat命令

(4)把 textfile1 的文档内容加上行号后输入 textfile2 这个文档里。

583
来自专栏漏斗社区

工具| sqlmap payload修改之路

文末有福利 前言 事情的起因是这样的:斗哥经常会发现一些骚气十足的注入规则,不过想要发挥这些注入规则少不了编写py脚本,小表姐作为sqlmap神器的忠实粉丝,...

3827

扫码关注云+社区