imanghafoori / laravel-microscope
自动测试您的 Laravel 应用程序
Requires
- php: ^7.2|8.0.*|8.1.*|8.2.*|8.3.*
- composer/class-map-generator: ^1.0.0
- imanghafoori/composer-json: ^1.0.17
- imanghafoori/php-abstract-filesystem: ^0.1.5
- imanghafoori/php-imports-analyzer: ^1.0.6
- imanghafoori/php-search-replace: ^1.1.13
- imanghafoori/php-token-analyzer: ^0.1.83
- imanghafoori/smart-realtime-facades: ^1.1.8
- jetbrains/phpstorm-attributes: 1.*
- laravel/framework: 5.*|6.*|7.*|8.*|9.*|10.*|11.*
Requires (Dev)
- orchestra/testbench: >=3.0.0
- phpunit/phpunit: >=6.0.0
- dev-master
- v1.0.369
- v1.0.368
- v1.0.367
- v1.0.366
- v1.0.365
- v1.0.364
- v1.0.363
- v1.0.362
- v1.0.361
- v1.0.360
- v1.0.359
- v1.0.358
- v1.0.357
- v1.0.356
- v1.0.355
- v1.0.354
- v1.0.353
- v1.0.352
- v1.0.351
- v1.0.350
- v1.0.349
- v1.0.348
- v1.0.347
- v1.0.346
- v1.0.345
- v1.0.344
- v1.0.343
- v1.0.342
- v1.0.341
- v1.0.340
- v1.0.339
- v1.0.338
- v1.0.337
- v1.0.336
- v1.0.335
- v1.0.334
- v1.0.333
- v1.0.332
- v1.0.331
- v1.0.330
- v1.0.329
- v1.0.328
- v1.0.327
- v1.0.326
- v1.0.325
- v1.0.324
- v1.0.323
- v1.0.322
- v1.0.321
- v1.0.320
- v1.0.319
- v1.0.318
- v1.0.317
- v1.0.316
- v1.0.315
- v1.0.314
- v1.0.313
- v1.0.312
- v1.0.311
- v1.0.310
- v1.0.309
- v1.0.308
- v1.0.307
- v1.0.306
- v1.0.305
- v1.0.304
- v1.0.303
- v1.0.302
- v1.0.301
- v1.0.300
- v1.0.299
- v1.0.298
- v1.0.297
- v1.0.296
- v1.0.295
- v1.0.294
- v1.0.293
- v1.0.292
- v1.0.291
- v1.0.290
- v1.0.289
- v1.0.288
- v1.0.287
- v1.0.286
- v1.0.285
- v1.0.284
- v1.0.283
- v1.0.282
- v1.0.281
- v1.0.280
- v1.0.279
- v1.0.278
- v1.0.277
- v1.0.276
- v1.0.275
- v1.0.274
- v1.0.273
- v1.0.272
- v1.0.271
- v1.0.270
- v1.0.269
- v1.0.268
- v1.0.267
- v1.0.266
- v1.0.265
- v1.0.264
- v1.0.263
- v1.0.262
- v1.0.261
- v1.0.260
- v1.0.259
- v1.0.258
- v1.0.257
- v1.0.256
- v1.0.255
- v1.0.254
- v1.0.253
- v1.0.252
- v1.0.251
- v1.0.250
- v1.0.249
- v1.0.248
- v1.0.247
- v1.0.246
- v1.0.245
- v1.0.244
- v1.0.243
- v1.0.242
- v1.0.241
- v1.0.240
- v1.0.239
- v1.0.238
- v1.0.237
- v1.0.236
- v1.0.235
- v1.0.234
- v1.0.233
- v1.0.232
- v1.0.231
- v1.0.230
- v1.0.229
- v1.0.228
- v1.0.227
- v1.0.226
- v1.0.225
- v1.0.224
- v1.0.223
- v1.0.222
- v1.0.221
- v1.0.220
- v1.0.219
- v1.0.218
- v1.0.217
- v1.0.216
- v1.0.215
- v1.0.214
- v1.0.213
- v1.0.212
- v1.0.211
- v1.0.210
- v1.0.209
- v1.0.208
- v1.0.206
- v1.0.205
- v1.0.204
- v1.0.203
- v1.0.202
- v1.0.201
- v1.0.200
- v1.0.199
- v1.0.198
- v1.0.197
- v1.0.196
- v1.0.195
- v1.0.194
- v1.0.193
- v1.0.192
- 1.0.191
- v1.0.189
- v1.0.188
- v1.0.187
- v1.0.186
- v1.0.185
- v1.0.184
- v1.0.183
- v1.0.182
- v1.0.181
- v1.0.180
- v1.0.179
- v1.0.178
- v1.0.177
- v1.0.176
- v1.0.175
- v1.0.174
- v1.0.173
- v1.0.172
- v1.0.171
- v1.0.170
- v1.0.169
- v1.0.168
- v1.0.167
- v1.0.166
- v1.0.165
- v1.0.164
- v1.0.163
- v1.0.162
- v1.0.161
- v1.0.160
- 1.0.159
- v1.0.158
- v1.0.157
- v1.0.156
- v1.0.155
- v1.0.154
- v1.0.153
- v1.0.152
- v1.0.151
- v1.0.150
- v1.0.149
- v1.0.148
- v1.0.147
- v1.0.146
- v1.0.145
- v1.0.144
- v1.0.143
- v1.0.142
- v1.0.141
- v1.0.140
- v1.0.139
- v1.0.138
- v1.0.136
- v1.0.135
- v1.0.134
- v1.0.133
- v1.0.132
- v1.0.131
- v1.0.130
- v1.0.129
- v1.0.128
- v1.0.127
- v1.0.126
- v1.0.125
- v1.0.124
- v1.0.123
- v1.0.122
- v1.0.121
- v1.0.119
- v1.0.118
- v1.0.117
- v1.0.116
- v1.0.115
- v1.0.114
- v1.0.113
- v1.0.112
- v1.0.111
- v1.0.110
- v1.0.109
- v1.0.108
- v1.0.107
- v1.0.106
- v1.0.105
- v1.0.104
- v1.0.103
- v1.0.101
- v1.0.100
- v1.0.99
- v1.0.98
- v1.0.97
- v1.0.96
- v1.0.95
- v1.0.94
- v1.0.93
- v1.0.92
- v1.0.91
- v1.0.90
- v1.0.89
- v1.0.88
- v1.0.87
- v1.0.86
- v1.0.85
- 1.0.84
- v1.0.83
- v1.0.82
- v1.0.81
- v1.0.80
- v1.0.79
- v1.0.77
- 1.0.76
- v1.0.75
- v1.0.74
- v1.0.73
- v1.0.72
- v1.0.71
- v1.0.66
- v1.0.65
- v1.0.64
- v1.0.63
- v1.0.61
- v1.0.60
- v1.0.59
- v1.0.58
- v1.0.57
- v1.0.51
- v1.0.50
- v1.0.49
- v1.0.48
- v1.0.47
- v1.0.46
- v1.0.44
- v1.0.43
- v1.0.41
- v1.0.40
- v1.0.39
- v1.0.38
- v1.0.37
- v1.0.35
- v1.0.34
- v1.0.33
- v1.0.32
- v1.0.30
- v1.0.29
- v1.0.28
- v1.0.27
- v1.0.26
- v1.0.25
- v1.0.24
- v1.0.22
- v1.0.21
- v1.0.19
- v1.0.18
- v1.0.15
- v1.0.14
- v1.0.12
- v1.0.11
- v1.0.10
- v1.0.9
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v0.1.57
- v0.1.55
- v0.1.54
- v0.1.52
- v0.1.51
- v0.1.50
- v0.1.48
- v0.1.47
- v0.1.46
- v0.1.41
- v0.1.40
- v0.1.39
- v0.1.38
- v0.1.37
- v0.1.36
- v0.1.35
- v0.1.34
- v0.1.32
- v0.1.29
- v0.1.27
- v0.1.21
- v0.1.20
- v0.1.18
- v0.1.16
- v0.1.15
- v0.1.13
- v0.1.11
- v0.1.9
- v0.1.7
- v0.1.5
- v0.1.4
- v0.1.3
- dev-generators
- dev-test
- dev-loaded_local_modules
- dev-case_sensitive
This package is auto-updated.
Last update: 2024-09-21 11:43:03 UTC
README
在它们咬你之前找到虫子
用❤️为懒惰的 Laravel 开发者构建 ;)
为什么重复旧错误,如果有这么多新错误要提交呢?
(伯特兰·罗素)
给你的眼睛休息一下,我们将为您检测和修复它们。
-
目录
-
显示命令
关键事项
- 它被创建为 比 PHPStorm 和其他 IDE 更聪明,以找到错误。
- 它被创建为 理解 Laravel 运行时 和魔法。
- 它不会显示给您愚蠢的假错误,所有报告的情况都是真正的错误。
- 即使您已经为您的应用程序编写了很多测试,您可能仍然需要这个。
- 它可以通过自动应用
early returns
来重构您的代码。 - 它是从头开始编写的,以产生可能的最大 性能。
🎞️ 视频教程 这里
⭐ 您的星星让我们做得更多
如果您发现这个包很有用,并且您想鼓励维护者继续工作,只需按星按钮声明您的意愿。
⬇️ 安装
您可以通过 Composer 安装 此包
composer require imanghafoori/laravel-microscope --dev
您还可以 发布 配置文件
php artisan vendor:publish --provider="Imanghafoori\LaravelMicroscope\LaravelMicroscopeServiceProvider"
💎 使用
有用命令
您可以运行 👇
较少使用的命令
全局辅助函数
此外,您将能够访问一些全局辅助函数
microscope_dd_listeners($event);
如果您想知道监听器是什么以及它们在哪里,您可以在 boot
或 register
方法中调用 microscope_dd_listeners(MyEvent::class);
。它就像一个正常的 dd(...);
一样工作,意味着程序将在那个点停止运行。
📖 命令做什么?
让我们从
php artisan search_replace {--name=pattern_name} {--tag=some_tag} {--file=partial_file_name} {--folder=partial_folder_name}
这是一个智能且非常强大的搜索/替换功能,可以为您节省大量时间。
1️⃣ 定义模式
如果您第一次运行
artisan search_replace
命令,它将在项目的根目录中创建一个search_replace.php
文件。然后,您可以在该文件中定义您的模式。
示例
让我们定义一个模式,用 ?->
PHP 8 空安全操作符替换全局辅助函数 optional()
。
return [ 'optional_to_nullsafe' => [ 'search' => '"<global_func_call:optional>"("<in_between>")->', 'replace' => '"<2>"?->', // 'tag' => 'php8,refactor', // 'predicate' => function($matches, $tokens) {...}, // 'mutator' => function($matches) {...}, // 'post_replace' => [...], // 'avoid_result_in' => [...], // 'avoid_syntax_errors' => false, // 'filters' => [...], ] ];
- 这里的关键字
optional_to_nullsafe
是您模式的“唯一名称”。(您可以通过运行php artisan search_replace --name=optional_to_nullsafe
来定位您的模式) - 搜索模式有一个
"<in_between>"
占位符,它捕获括号之间的所有内容。 - 在
replace
块中,我们用第一个占位符替换我们捕获的内容为"<1>"
。如果我们有更多占位符,我们可以有"<2>"
等。 - 在标签块中,我们可以指定一些标签,作为字符串数组或用逗号分隔的字符串,并通过
--tag
标志进行定位:php artisan search_replace --tag=php8
这里是一个您可以使用占位符的完整列表
如果需要,您也可以定义自己的关键字!
您只需定义一个类作为您的新关键字,并将类路径追加到
Finder::$keywords[] = MyKeyword::class
属性的末尾。就像默认关键字一样。
示例
1️⃣ 假设您只想找到包含“todo:”单词的“注释”。
'todo_comments' => [ 'search' => '<comment>', 'predicate' => function($matches) { // <==== here we check comment has "todo:" $comment = $matches[0]; // first placeholder value $content = $comment[1]; // get its content return Str::contains($content, 'todo:') ? true : false; }, ]
注意 如果您没有提到 'replace'
键,它只会搜索并报告给您。
2️⃣ 好的,现在假设您想从注释中移除“todo:”单词
'remove_todo_comments' => [ 'search' => '<comment>', // <=== we capture any comment 'replace' => '<1>', 'predicate' => function($matches) { $comment = $matches[0]; // first matched placeholder $content = $comment[1]; return Str::contains($content, 'todo:') ? true : false; }, 'mutator' => function ($matches) { // <=== here we remove "todo:" $matches[0][1] = str_replace('todo:', '', $matches[0][1]); return $matches; } ]
转换: // todo: refactor code
成: // refactor code
3️⃣ 突变体: 在突变体中,您可以在替换结果之前,自由地按照所需程度操纵 $matched
值。您还可以指定一个静态方法而不是函数,例如:[MyClass::class, 'myStaticMethod']
3️⃣ 假设您想在数组中为缺少的 Let's 元素添加可选逗号。
'enforce_optional_comma' => [ 'search' => '<white_space>?]', 'replace' => ',"<1>"]', 'avoid_syntax_errors' => true, 'avoid_result_in' => [ ',,]', '[,]', '<var>[,]' ], ]
在这种情况下,我们的模式不是很准确,在某些情况下,它可能会导致语法错误。因此,我们打开 PHP 语法验证器来检查结果,但这会给我们带来性能损失!!!为了排除 PHP 的使用,我们提到了 avoid_result_in
,以便如果它们出现在结果中,则跳过。
- 注意:在 "<white_space>?" 的 "
?
" 中标记这是一个optional
占位符。
如果您想看到一个不需要任何语法检查的更好的模式,请尝试这个
'enforce_optional_comma' => [
'search' => '<1:any><2:white_space>?[<3:until_match>]',
'replace' => '<1><2>[<3>,]',
'avoid_result_in' => [
',,]',
'[,]'
],
'predicate' => function ($matches) {
$type = $matches['values'][0][0];
return $type !== T_VARIABLE && $type !== ']';
},
'post_replace' => [
'<1:white_space>,]' => ',<1>]'
]
],
这更复杂,但速度更快。(因为它不需要 PHP 语法验证器)
-
这里
'post_replace'
是一个仅应用于结果代码以精炼它的模式,而不是应用于整个文件。 -
您可以选择注释您的占位符(如上
<1:any>
),并使用数字,以便在替换时知道哪个对应哪个。
目前,显微镜只提供了两个内置过滤器: is_sub_class_of
和 in_array
你能猜出这个模式在做什么吗?!
'mention_query' => [ 'search' => '<1:class_ref>::<2:name>' 'replace' => '<1>::query()-><2>', 'filters' => [ 1 => [ 'is_sub_class_of' => \Illuminate\Database\Eloquent\Model::class ], 2 => [ 'in_array' => 'where,count,find,findOrFail,findOrNew' ] ] ]
它将这些转换为
User::where(...)->get(); \App\Models\User::find(...);
成为这些
User::query()->where(...)->get(); \App\Models\User::query()->find(...);
- 这里的过滤器确保捕获的类引用是 Laravel 模型,并且方法名是列表中提到的名称之一。
所以它不会干扰像这样的事情
User::all(); // The `all` method can not be preceded by `query` UserRepo::where(...); /// UserRepo is not a model
- 这是您永远无法通过正则表达式做到的事情。
假设我们想选择 PHP v7.4 箭头函数
'fn' => [ 'search' => 'function (<in_between>)<until>{ return <statement>; }', 'replace' => 'fn (<1>) => <3>', 'tags' => 'php74,refactor', ]
在这个例子中,我们在函数体中提到了一个单独的“语句”。因此,如果它遇到包含两个或更多语句的函数,它将忽略它。
$closure = function ($a) use ($b) { return $a + $b; }; // will become: $closure = fn($a) => $a + $hello;
但这个没有被捕获
$closure = function ($a) { $a++; return $a + $b; };
6️⃣ <statement>
和 <until>
之间的区别:
它们看起来非常相似,但有一个重要的情况,您不能使用 <until>
来正确地覆盖它!
$first = $a + $b; $second = function ($a) { $a++; return $a; };
如果我们像这样定义我们的模式
return [ 'pattern_name' => [ 'search' => '<var> = <until>;', ] ];
对于$c = $a + $b;
,它们的行为相同,但对于第二个"<until>"
,它将不会捕获整个闭包,而会在到达$a++;
时停止,这是一个问题。
但如果你将模式定义为:'<var> = <statement>'
,它将足够智能,能够捕获闭包定义末尾的正确分号,并且整个闭包将被捕获。
假设你希望在推向生产之前消除所有dd(...)
或dump(...)
。
return [ 'remove_dd' => [ 'search' => "'<global_func_call:dd,dump>'('<in_between>');", 'replace' => '' ] ];
这不会捕获以下情况
$this-> dd('hello'); // is technically a method call User:: dd('I am static'); // is technically a static method call new dd('I am a class'); // here "dd" is the name of a class.
但它会检测并删除带有任何参数的实际全局dd()
调用。
dd( // <=== will be detected, even if the pattern above is written all in one line.
auth('admin')
->user()->id
);
\dd(1);
dd(1);
dump(1);
假设我们想要重构
User:where('name', 'John')->where('family', 'Dou')->where('age', 20)->get();
为
User:where([ 'name' => 'John', 'family' => 'Dou', 'age'=> 20, ])->get();
那么这个模式会是什么样子呢?!
"group_wheres" => [ 'search' => '<1:class_ref>::where('<2:str>', '<3:str>')'<repeating:wheres>'->get();' 'replace' => '<1>::where([ <2> => <3>, "<repeating:1:key_values>"])->get();', 'named_patterns' => [ 'wheres' => '->where(<str>, <str>)<white_space>?', 'key_values' => '<1> => <2>,<3>', ] ]
太棒了,不是吗?!
可能性是无限的,天空才是极限...
php artisan check:early_returns
这将扫描所有你的Psr-4加载的类,并应用早期返回规则来简化函数和循环。例如
<?php foreach ($products as $product) { if ($someCond) { // A lot of code 1 // A lot of code 1 // A lot of code 1 // A lot of code 1 // A lot of code 1 if ($someOtherCond) { // A lot more code 2 // A lot more code 2 // A lot more code 2 // A lot more code 2 // A lot more code 2 // } // <--- closes second if } // <--- closes first if }
将会被发现并转换为
<?php foreach ($products as $product) { if (! $someCond) { continue; } // A lot of code 1 // A lot of code 1 // A lot of code 1 // A lot of code 1 // A lot of code 1 if (! $someOtherCond) { continue; } // A lot more code 2 // A lot more code 2 // A lot more code 2 // A lot more code 2 // A lot more code 2 }
相同的事情也会应用到函数和方法上,但使用return
<?php if ($cond1) { if ($cond2) { .... } } // we get merged into: if ($cond1 && $cond2) { ... }
- 它还支持类似Ruby的if():/endif;语法;
<?php if ($var1 > 1): if ($var2 > 2): echo 'Hey Man'; endif; endif; // Or if you avoid putting curly braces... if ($var1 > 1) if ($var2 > 2) echo 'Hey Man';
虽然这种重构是安全的,并且保证与之前执行相同的事情,但在尝试此功能之前,请小心提交所有内容,以防出现奇怪的错误或类似情况。
php artisan check:psr4
- 它检查composer.json文件中定义的所有PSR4自动加载,并遍历所有类以获得正确的命名空间,根据PSR-4标准。
- 它会自动根据PSR-4规则修正命名空间。
- 它还会检查对旧命名空间的引用,并将其替换为新命名空间。
php artisan check:generate
你创建一个空文件,我们根据命名约定来填充它。
如果你在运行此命令后创建一个空.php
文件,该文件以ServiceProvider.php
结尾:1 - 它将被填充为样板和正确的Psr-4命名空间。2 - 它将被添加到config/app.php
中的providers
数组中。
php artisan check:imports
- 它检查所有导入(
use
语句)是否有效,并报告无效的导入。 - 它会自动修正一些引用,确保类名没有歧义。
- 它可以理解Laravel别名类,因此
use Request;
是有效的。
php artisan check:bad_practices
- 它检测不良做法,如配置文件外的
env()
调用。
php artisan check:routes
- 它检查你的路由是否引用有效的控制器类和方法。
- 它检查所有控制器方法都有有效的类型提示。
- 它扫描
route()
、redirect()->route()
、\Redirect::route()
是否引用有效的路由。 - 它将报告没有路由指向它们的控制器公共方法。换句话说,检测到
死控制器
。
php artisan check:compact
- 在PHP 7.3中,如果你“紧凑”一个不存在的变量,你会得到一个错误,因此此命令会检查整个项目中的错误
compact()
调用,并向你报告应该删除哪些参数。
php artisan check:blade_queries
- Blade文件不应该包含数据库查询。我们应该将它们移回控制器并传递变量。此命令在所有Blade文件中搜索
Eloquent模型
和DB
查询构建器,并在找到任何时显示它们。
php artisan check:extract_blades
- 如果你想要提取一个Blade部分并使其包含,如下所示:
@include('myPartials.someFile')
你可以在你的Blade文件中使用{!! extractBlade('myPartials.someFile') !!}
来指示起始/结束行
和你要创建的路径/名称
的片段。
<html> {!! extractBlade('myPartials.head') !!} <head>...</head> {!! extractBlade() !!} {!! extractBlade('myPartials.body') !!} <body>...</body> {!! extractBlade() !!} </html>
执行php artisan check:extract_blades
后,它将变为
<html> @include('myPartials.head') @include('myPartials.body') </html>
此外,它还将创建
resources/views/myPartials/head.blade.php
resources/views/myPartials/body.blade.php
并将相应的内容放入它们中。
- 它还兼容模块化Laravel应用中的命名空间视图。因此,此语法将生效:
'MyMod::myPartials.body'
php artisan check:action_comments {--file=SomeFile.php}
- 这会在控制器动作中添加注解,以便你知道哪个路由指向当前的控制器动作。
- 您可以使用
--file=
选项来缩小扫描的文件范围。
php artisan pp:route
- 首先,您必须在路由文件中添加此代码:
microscope_pretty_print_route('my.route.name');
- 您也可以将Controller@method语法传递给函数。
- 您可以多次调用它来美化打印多个路由。
php artisan check:views
- 它扫描您的代码,并查找
view()
和View::make()
,并报告它们是否指向错误的文件。 - 它扫描您的blade文件中的
@include()
和@extends()
,并报告它们是否指向错误的文件。
此外,它可以检测从控制器传递到视图中的未使用变量
,例如:view('hello', [...]);
为了这样做,您必须在浏览器中打开页面,然后访问日志文件以查看类似以下的消息
local.INFO: Laravel Microscope: The view file: welcome.index-1 at App\Http\Controllers\HomeController@index has some unused variables passed to it:
local.INFO: array ('$var1' , '$var2');
请注意,一些变量是从view composer
而不是控制器传递到视图的。在检测未使用的变量时,也会考虑这些变量。
php artisan check:events
例如,考虑以下情况
Event::listen(MyEvent::class, '\App\Listeners\MyListener@myMethod');
1 - 它检查\App\Listeners\MyListener
类路径是否有效。
2 - 它检查myMethod
方法是否存在于MyListener
类中。
3 - 它检查myMethod
方法在签名中是否具有正确的类型提示(如果有),例如
public function myMethod(OtherEvent $e) // <---- notice type-hint here { // }
这是一个有效的但错误的类型提示,并将向您报告。很酷,不是吗 ??!
- 请注意,您如何设置事件监听器并不重要,
1- 在EventServiceProvider
中,
2- 通过Event::listen
外观,
3- 通过订阅器类...或任何其他方式。错误将被发现。 :)
php artisan check:gates
它检查您定义的所有守卫的有效性,确保它们引用有效的类和方法。
它还检查策略定义是否有效。
Gate::policy(User::class, 'UserPolicy@someMethod'); Gate::define('someAbility', 'UserGate@someMethod');
1 - 它检查User
类路径是否有效。
2 - 它检查UserPolicy
类路径是否有效。
3 - 它检查someMethod
方法是否存在。
php artisan check:dynamic_where
- 它查找“动态where”方法,如
whereFamilyName('...')
和where('family_name', '...')
。
php artisan enforce:query
-
它调用您的Eloquent查询链上的静态
query
方法,以便IDE可以理解Eloquent。 -
例如,将
User::where(...
转换为User::query()->where(...
php artisan check:dead_controllers
- 我们可以找到没有任何路由的控制器。
php artisan check:generic_docblocks {--folder=app/Models} {--file=SomeFile.php}
- 移除Laravel的DocBlocks。
- 您可以使用
--folder=
或--file=
选项来缩小扫描的文件夹。
php artisan enforce:helper_functions {--folder=app/Models} {--file=SomeFile.php}
- 将Laravel外观转换为辅助函数。
- 您可以使用
--folder=
或--file=
选项来缩小扫描的文件夹。
php artisan list:models {--folder=app/Models}
- 它在项目中搜索并列出模型类。
- 您可以使用
--folder=
选项来缩小扫描的文件夹。
并将很快添加更多功能。 ;)
致谢
许可
MIT许可证(MIT)。有关更多信息,请参阅许可文件
🙋 贡献
如果您发现一个问题或有更好的做事方式,请随时打开一个问题或拉取请求。如果您在开源项目中使用laravel-microscope,请创建一个拉取请求,在README.md文件中将它的URL作为示例应用程序提供。
❗ 安全性
如果您发现任何安全相关的问题,请通过电子邮件 imanghafoori1@gmail.com
联系,而不是使用问题跟踪器。
作者的其他作品
Laravel HeyMan
💎 允许我们编写表达式的代码来授权、验证和认证。
Laravel Terminator
💎 一个最小化但功能强大的包,允许您重构您的控制器。
Laravel AnyPass
💎 仅在本地环境中允许您使用任何密码登录。
A man will never fail unless he stops trying.
Albert Einstein
❤️ 贡献者
本项目得益于所有贡献者。 [贡献者].