Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
hector committed Jul 24, 2019
0 parents commit 69cefdd
Show file tree
Hide file tree
Showing 10 changed files with 1,732 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/vendor
/.idea
/.vscode
composer.lock
72 changes: 72 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# thinkphp-generator

命令行自动生成数据表模型、校验器、控制器等

## 框架要求

ThinkPHP5.1+

## 安装

~~~ bash
composer require hectorqin/thinkphp-generator
~~~

## 配置

修改项目根目录下config/generator.php中对应的参数

## 使用

~~~ bash
# 帮助
$ php think generate --help
Usage:
generate [options]

Options:
-c, --config[=CONFIG] 配置名称,默认为 generator [default: "generator"]
-t, --table[=TABLE] 要生成的table,多个用,隔开, 默认为所有table
-p, --tablePrefix[=TABLEPREFIX] table前缀,多个用,隔开
-i, --ignoreFields[=IGNOREFIELDS] 忽略的字段,不生成搜索器
-e, --except[=EXCEPT] 要排除的table,多个用,隔开
--type[=TYPE] 要生成的类型,多个用,隔开,如 m,v,c,p,s,d
m -- model, v -- validate, c -- controller, p -- postmanJson, s -- searchAttr, d -- model doc
--templateDir[=TEMPLATEDIR] 自定义模板文件夹路径,必须有 model.tpl,
controller.tpl, validate.tpl等文件,使用tp模板语法
--mModule[=MMODULE] 模型模块名
--vModule[=VMODULE] 校验器模块名
--cModule[=CMODULE] 控制器模块名
--mLayer[=MLAYER] 模型分层
--vLayer[=VLAYER] 校验器分层
--cLayer[=CLAYER] 控制器分层
--mBase[=MBASE] 模型继承类,如 app\common\model\EventModel
--vBase[=VBASE] 校验器继承
--cBase[=CBASE] 控制器继承类
--db[=DB] 数据库配置文件名
--dryRun[=DRYRUN] 只执行,不保存 [default: false]
-f, --force[=FORCE] 覆盖已存在文件 [default: false]
--pName[=PNAME] PostMan 项目名称,默认使用 数据库名
--pHost[=PHOST] PostMan API请求前缀,默认使用 api_prefix 环境变量
-h, --help Display this help message
-V, --version Display this console version
-q, --quiet Do not output any message
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

# 生成 user 表模型、校验器、控制器
php think generate -t user --type=m,v,c

# 生成数据库全部数据表的模型、校验器、控制器
php think generate --type=m,v,c

# 不生成,预览操作
php think generate --type=m,v,c -d

~~~

## License

Apache-2.0
29 changes: 29 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "hectorqin/thinkphp-generator",
"description": "Generate model,controller,validate with parsing database.",
"type": "think-extend",
"version": "0.0.2",
"license": "Apache-2.0",
"authors": [
{
"name": "hector",
"email": "hectorqin@163.com"
}
],
"autoload": {
"psr-4": {
"think\\generator\\": "src"
},
"files": [
"src/helper.php"
]
},
"require": {
"topthink/framework": "5.1.*"
},
"extra": {
"think-config": {
"generator": "src/config.php"
}
}
}
103 changes: 103 additions & 0 deletions src/command/AST.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php
namespace app\common\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\facade\Env;

class AST extends Command
{
protected function configure()
{
$this->setName('AST')
->addOption('type', null, Option::VALUE_OPTIONAL, "要解析的类型,多个用,隔开,如 m,c\n m -- model, c -- controller")
->addOption('scope', null, Option::VALUE_OPTIONAL, "要解析的范围,多个用,隔开,如 c,m\n c -- const, m -- method")
->addOption('dryRun', null, Option::VALUE_OPTIONAL, "只执行,不保存")
->setDescription('Print AST of file');
}

protected function execute(Input $input, Output $output)
{
$typeList = ['m', 'c'];
$scopeList = ['c', 'm'];

$dryRun = false;
if ($input->hasOption('dryRun')) {
$dryRun = $input->getOption('dryRun');
}

if ($input->hasOption('type')) {
$typeList = explode(',', $input->getOption('type'));
}

if ($input->hasOption('scope')) {
$scopeList = explode(',', $input->getOption('scope'));
}

$date = date("Ymd_Hi");
if (in_array('m', $typeList)) {
$this->generateTypeAST("./application/common/model/**.php", $scopeList, $dryRun ? false : Env::get('app_path') . "modelAST-{$date}.json");
}
if (in_array('c', $typeList)) {
$this->generateTypeAST("./application/index/controller/**.php", $scopeList, $dryRun ? false : Env::get('app_path') . "controllerAST-{$date}.json");
}
}

protected function generateTypeAST($globPattern, $scopeList, $savePath)
{
$ASTData = [];
$generateConstant = in_array('c', $scopeList);
$generateMethod = in_array('m', $scopeList);
foreach (glob($globPattern) as $file) {
$className = str_replace(['./application', '.php', '/'], ['/app', '', '\\'], $file);
$class = new \ReflectionClass($className);
if ($generateConstant) {
$constants = $class->getReflectionConstants();

foreach ($constants as $constant) {
if ($constant->class != $class->name) {
continue;
}
if (!in_array($constant->name, ['EVENT_INSERT', 'EVENT_UPDATE', 'EVENT_DELETE'])) {
$ASTData[$class->name]['constant'][] = [
'name' => $constant->name,
'value' => $constant->getValue(),
'doc' => str_replace(["/**\n", "* ", '*/'], '', $constant->getDocComment()),
];
}
}
}

if ($generateMethod) {
$methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);

foreach ($methods as $method) {
if ($method->class != $class->name) {
continue;
}
$args = [];
foreach ($method->getParameters() as $arg) {
$args[] = [
'name' => $arg->name,
'default' => $arg->isDefaultValueAvailable() ? $arg->getDefaultValue() : '',
];
}
$ASTData[$class->name]['method'][] = [
'name' => $method->name,
'__toString' => $method->__toString(),
'args' => $args,
'doc' => str_replace(["/**\n", "* ", '*/'], '', $method->getDocComment()),
];
}
}
}
// dump($ASTData);
if ($savePath) {
file_put_contents($savePath, json_encode($ASTData, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
} else {
dump($ASTData);
}
}
}
Loading

0 comments on commit 69cefdd

Please sign in to comment.