imanghafoori / laravel-microscope
Automatically test your laravel application
Package info
github.com/imanghafoori1/laravel-microscope
pkg:composer/imanghafoori/laravel-microscope
Requires
- php: ^7.4|8.0.*|8.1.*|8.2.*|8.3.*|8.4.*|8.5.*
- composer/class-map-generator: ^1.0.0
- illuminate/auth: 6.*|7.*|8.*|9.*|10.*|11.*|12.*|13.*
- illuminate/console: 6.*|7.*|8.*|9.*|10.*|11.*|12.*|13.*
- illuminate/contracts: 6.*|7.*|8.*|9.*|10.*|11.*|12.*|13.*
- illuminate/filesystem: 6.*|7.*|8.*|9.*|10.*|11.*|12.*|13.*
- illuminate/routing: 6.*|7.*|8.*|9.*|10.*|11.*|12.*|13.*
- illuminate/support: 6.*|7.*|8.*|9.*|10.*|11.*|12.*|13.*
- illuminate/view: 6.*|7.*|8.*|9.*|10.*|11.*|12.*|13.*
- imanghafoori/composer-json: ^2.1.0
- imanghafoori/php-abstract-filesystem: ^0.1.6
- imanghafoori/php-imports-analyzer: ^1.1.0
- imanghafoori/php-search-replace: ^1.1.16
- imanghafoori/php-token-analyzer: ^0.1.90
- imanghafoori/smart-realtime-facades: ^1.1.9
- jetbrains/phpstorm-attributes: 1.*
Requires (Dev)
- phpunit/phpunit: >=10.0.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-master
- v7.4.x-dev
- v1.0.443
- v1.0.442
- v1.0.441
- v1.0.440
- v1.0.439
- v1.0.437
- v1.0.436
- v1.0.435
- v1.0.434
- v1.0.433
- v1.0.432
- v1.0.431
- v1.0.430
- v1.0.429
- v1.0.428
- v1.0.427
- v1.0.426
- v1.0.425
- v1.0.424
- v1.0.423
- v1.0.422
- v1.0.421
- v1.0.420
- v1.0.419
- v1.0.418
- v1.0.417
- v1.0.415
- v1.0.414
- v1.0.413
- v1.0.412
- v1.0.411
- v1.0.410
- v1.0.409
- v1.0.408
- v1.0.407
- v1.0.406
- v1.0.405
- v1.0.404
- v1.0.403
- v1.0.402
- v1.0.401
- v1.0.400
- v1.0.399
- v1.0.398
- v1.0.397
- v1.0.396
- v1.0.395
- v1.0.394
- v1.0.393
- v1.0.392
- v1.0.391
- v1.0.390
- v1.0.389
- v1.0.388
- v1.0.387
- v1.0.386
- v1.0.385
- v1.0.384
- v1.0.383
- v1.0.382
- v1.0.381
- v1.0.379
- v1.0.378
- v1.0.377
- v1.0.376
- v1.0.375
- v1.0.374
- v1.0.373
- v1.0.372
- v1.0.371
- v1.0.370
- 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: 2026-10-20 21:52:26 UTC
README
Built with ❤️ for lazy Laravel developers ;)
Check the vibe-coded project to make sure it passes health checks.
AI hallucinations are never going to end.
Table of Contents
- Key Things To Know
- Installation
- Usage
- What The Commands Do
search_replacecheck:early_returnscheck:psr4check:importscheck:bad_practicescheck:routescheck:compactcheck:blade_queriescheck:extract_bladescheck:action_commentscheck:viewscheck:gatescheck:aliasescheck:dead_controllerscheck:generic_docblockscheck:abort_ifcheck:dynamic_wherecheck:extra_fqcncheck:extra_importsenforce:importsenforce:helper_functionsenforce:querylist:models
- Credits
- License
- Contributing
- More From The Author
- Contributors
Key Things To Know
- It is created to be smarter than PhpStorm and other IDEs in finding errors.
- It is created to understand Laravel runtime and magic.
- It does not show you stupid false errors — every reported case is really an error.
- Even if you have written a lot of tests for your app, you may still need this.
- It can refactor your code, by applying early returns automatically.
- It is written from scratch to yield the maximum possible performance.
⭐ Your Stars Make Us Do More
If you found this package useful and you want to encourage the maintainer to work on it, just press the star button to declare your willingness.
⬇️ Installation
Install the package via Composer:
composer require imanghafoori/laravel-microscope --dev
Optionally publish the config file:
php artisan vendor:publish --provider="Imanghafoori\LaravelMicroscope\LaravelMicroscopeServiceProvider"
💎 Usage
Useful Commands
You can run 👇
| # | Artisan Command |
|---|---|
| 1 | php artisan search_replace |
| 2 | php artisan check:early_returns |
| 3 | php artisan check:all |
Less Used Commands
| # | Artisan Command |
|---|---|
| 1 | php artisan check:views |
| 2 | php artisan check:routes |
| 3 | php artisan check:psr4 {-s|--nofix} |
| 4 | php artisan check:imports {-s|--nofix} |
| 5 | php artisan check:stringy_classes |
| 6 | php artisan check:dd |
| 7 | php artisan check:bad_practices |
| 8 | php artisan check:compact |
| 9 | php artisan check:blade_queries |
| 10 | php artisan check:action_comments |
| 11 | php artisan check:extract_blades |
| 12 | php artisan check:abort_if |
| 13 | php artisan list:models |
| 14 | php artisan check:endif |
| 15 | php artisan check:gates |
| 16 | php artisan check:dynamic_where |
| 17 | php artisan check:aliases |
| 18 | php artisan check:dead_controllers |
| 19 | php artisan check:generic_docblocks |
| 20 | php artisan enforce:helper_functions |
| 21 | php artisan enforce:imports |
| 22 | php artisan check:fqcn |
📖 What Do The Commands Do?
Let's start with:
php artisan search_replace
php artisan search_replace
{--name=pattern_name}
{--tag=some_tag}
{--file=partial_file_name}
{--folder=partial_folder_name}
{--except-folder=}
{--except-file=}
A smart and very powerful search/replace functionality that can be a real time saver.
1️⃣ Defining Patterns
If you run
php artisan search_replacefor the first time, it will create asearch_replace.phpfile in the project's root. Then you can define your patterns within that file.
Example: replace the optional() global helper with the PHP 8 ?-> null-safe operator.
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' => [...], ], ];
- The key
optional_to_nullsafeis the unique name of your pattern. Target it with:php artisan search_replace --name=optional_to_nullsafe
<in_between>captures everything between a pair of parentheses.- In
replace,<1>substitutes the first placeholder,<2>the second, and so on. tagcan be a string (comma-separated) or an array. Target it with:php artisan search_replace --tag=php8
2️⃣ Placeholders
| # | Placeholder | Description |
|---|---|---|
| 1 | <var> or <variable> |
Variables like $user |
| 2 | <str> or <string> |
Hard-coded strings: 'hello' or "hello" |
| 3 | <class_ref> |
Class references: \App\User::where(...), User::where |
| 4 | <full_class_ref> |
Full references only: \App\User:: |
| 5 | <until> |
Capture all code until a certain character |
| 6 | <comment> |
Comments (does not capture doc-blocks beginning with /**) |
| 7 | <doc_block> |
PHP doc-blocks |
| 8 | <statement> |
A whole PHP statement |
| 9 | <name:nam1,nam2> or <name> |
Method or function names: ->where or ::where |
| 10 | <white_space> |
Whitespace blocks |
| 11 | <bool> or <boolean> |
true or false (case-insensitive) |
| 12 | <number> |
Numeric values |
| 13 | <cast> |
Type-casts like (array) $a; |
| 14 | <int> or <integer> |
Integer values |
| 15 | <visibility> |
public, protected, private |
| 16 | <float> |
Floating-point numbers |
| 17 | "<global_func_call:func1,func2>" |
Detect global function calls |
| 18 | <in_between> |
Capture code within a pair of {...}, (...), or [...] |
| 19 | <any> |
Capture any token |
You can also define your own keywords. Create a class for your keyword and append its classpath to
Finder::$keywords[] = MyKeyword::class, just like the defaults.
Example 1: find only comments containing the word todo:.
'todo_comments' => [ 'search' => '<comment>', 'predicate' => function ($matches) { $comment = $matches[0]; // first placeholder value $content = $comment[1]; // its content return Str::contains($content, 'todo:') ? true : false; }, ],
Note If you do not mention the 'replace' key, it only searches and reports them to you.
2️⃣ Ok, now let's say you want to remove the "todo:" word from your comments:
'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; } ]
Converts: // todo: refactor code
Into: // refactor code
3️⃣ Mutator
In mutators, you are free to manipulate the $matched values as much as you need before they get replaced. You can also use a static method instead of a closure: [MyClass::class, 'myStaticMethod'].
Example: enforce an optional trailing comma in arrays.
'enforce_optional_comma' => [ 'search' => '<white_space>?]', 'replace' => ',"<1>"]', 'avoid_syntax_errors' => true, 'avoid_result_in' => [ ',,]', '[,]', '<var>[,]', ], ],
This pattern isn't perfectly accurate, so we enable the PHP syntax validator (a performance cost) and list avoid_result_in strings so the validator is skipped when those appear in the result.
The
?in<white_space>?marks the placeholder as optional.
A faster, syntax-check-free alternative:
'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>]', ], ],
post_replaceis applied only to the resulting code — not the whole file.- You can annotate placeholders with numbers (
<1:any>) to know which one maps to which.
4️⃣ Filters
Two built-in filters: is_sub_class_of and 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', ], ], ],
Converts:
User::where(...)->get(); \App\Models\User::find(...);
into:
User::query()->where(...)->get(); \App\Models\User::query()->find(...);
Filters ensure the captured class is an Eloquent model and the method name is in the list, so it leaves alone:
User::all(); // `all` cannot be preceded by `query` UserRepo::where(...); // UserRepo is not a model
This is something you can never do with regex alone.
5️⃣ Capturing PHP Statements
Opt into PHP 7.4 arrow functions:
'fn' => [ 'search' => 'function (<in_between>)<until>{ return <statement>; }', 'replace' => 'fn (<1>) => <3>', 'tags' => 'php74,refactor', ],
Because we specified exactly one <statement> in the body, only single-statement closures are captured:
$closure = function ($a) use ($b) { return $a + $b; }; // becomes: $closure = fn ($a) => $a + $b;
Multi-statement closures are ignored:
$closure = function ($a) { $a++; return $a + $b; };
6️⃣ <statement> vs <until>;
They look similar, but there is an important case where <until>; fails:
$first = $a + $b; $second = function ($a) { $a++; return $a; };
With:
'pattern_name' => [ 'search' => '<var> = <until>;', ],
- For
$c = $a + $b;both behave the same. - For the second one,
<until>;stops at$a++;— a problem.
Using <var> = <statement> is smart enough to capture the correct terminating semicolon of the closure definition.
7️⃣ Capturing Global Function Calls
Remove dd(...) / dump(...) before pushing to production:
return [ 'remove_dd' => [ 'search' => "'<global_func_call:dd,dump>'('<in_between>');", 'replace' => '', ], ];
This will not match:
$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.
But will detect and remove real global dd() calls with whatever parameters they have received.
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);
Refactor:
User::where('name', 'John')->where('family', 'Dou')->where('age', 20)->get();
into:
User::where([ 'name' => 'John', 'family' => 'Dou', 'age' => 20, ])->get();
Pattern:
"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>', ] ]
Nice, right? Possibilities are endless — the sky is the limit.
php artisan check:early_returns
Scans all your PSR-4 loaded classes and flattens functions and loops by applying the early-return rule.
<?php foreach ($products as $product) { if ($someCond) { // A lot of code 1 if ($someOtherCond) { // A lot more code 2 } } }
becomes:
<?php foreach ($products as $product) { if (! $someCond) { continue; } // A lot of code 1 if (! $someOtherCond) { continue; } // A lot more code 2 }
The same applies to functions and methods, but with return. Nested ifs get merged:
<?php if ($cond1) { if ($cond2) { .... } } // we get merged into: if ($cond1 && $cond2) { ... }
It also supports the Ruby-like if(): ... endif; syntax and brace-less bodies.
php artisan check:psr4
Checks (and optionally fixes) namespace declarations in your project to ensure they comply with PSR-4 autoloading standards. The command scans your classes, compares each declared namespace against the expected namespace derived from its file path and composer.json autoload configuration, and can automatically correct mismatches — including references to renamed classes elsewhere in your codebase.
php artisan check:psr4 [options]
Options
| Option | Shortcut | Description |
|---|---|---|
--detailed |
-d |
Show the classes being checked while the command runs. |
--force |
-f |
Fix namespaces without asking for confirmation. |
--nofix |
-s |
Skip fixing namespaces and only report them. |
--force-ref-fix |
-o |
Fix references to renamed classes without asking for confirmation. |
--no-ref-fix |
-r |
Skip searching for and fixing references to renamed classes. |
--watch |
-w |
Re-run the command every 8 seconds (useful during development). |
--folder= |
Filter the check to files in folders whose path contains the given partial name. |
Examples
# Basic interactive check php artisan check:psr4 # Report only, never modify files php artisan check:psr4 --nofix # Fix namespaces automatically php artisan check:psr4 --force # Fully unattended fix (e.g., CI) php artisan check:psr4 --force --force-ref-fix # Limit to a folder php artisan check:psr4 --folder=app/Models
php artisan check:imports
php artisan check:imports {--file=} {--folder=} {--except-folder=} {--except-file=}
- Checks all imports (
usestatements) and reports invalid ones. - Auto-corrects references when there is no ambiguity around the class name.
- Understands Laravel aliased classes, so
use Request;is valid.
php artisan check:bad_practices
Detects bad practices — e.g., env() calls outside config files.
php artisan check:routes
- Checks that routes refer to valid controller classes and methods.
- Checks that controller methods have valid type-hints.
- Scans
route(),redirect()->route(), and\Redirect::route()for references to valid routes. - Reports public controller methods with no route pointing to them (dead controllers).
php artisan check:compact
In PHP 7.3, compact() on a non-existent variable raises an error. This command scans the whole project for wrong compact() calls and reports which parameters to remove.
php artisan check:blade_queries
Blade files should not contain DB queries — move them back into controllers and pass variables. This command scans all Blade files for Eloquent models and the DB query builder and reports them.
php artisan check:extract_blades
Extract a Blade partial and include it. Use {!! extractBlade('myPartials.someFile') !!} to mark the start/end lines and path/name of the partial.
<html> {!! extractBlade('myPartials.head') !!} <head>...</head> {!! extractBlade() !!} {!! extractBlade('myPartials.body') !!} <body>...</body> {!! extractBlade() !!} </html>
After php artisan check:extract_blades:
<html> @include('myPartials.head') @include('myPartials.body') </html>
It also creates:
resources/views/myPartials/head.blade.phpresources/views/myPartials/body.blade.php
with the corresponding content. Namespaced views (modular apps) are supported too: 'MyMod::myPartials.body'.
php artisan check:action_comments
php artisan check:action_comments {--file=SomeFile.php}
Adds annotations in controller actions so you know which route points to the current action. Use --file= to narrow down the scanned files.
php artisan check:views
- Scans your code for
view()andView::make()and reports references to missing files. - Scans Blade files for
@include()and@extends()and reports references to missing files. - Detects unused variables passed from a controller, e.g.
view('hello', [...]).
To detect unused variables, open the page in the browser, then check the log file:
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');
Variables passed via a view composer are also considered when detecting unused variables.
php artisan enforce:imports
Refactors your code by importing fully qualified class namespaces at the top as use statements. Use --class=MyCls1,MyCls2 to limit which class names are imported.
php artisan check:abort_if
Refactors:
<?php if ($some === 'Condition') { abort(404, 'optional message.'); }
into:
<?php abort_if($some === 'Condition', 404, 'optional message.');
php artisan check:gates
Checks the validity of all gates, ensuring they refer to a valid class and method. Also checks policy definitions:
Gate::policy(User::class, 'UserPolicy@someMethod'); Gate::define('someAbility', 'UserGate@someMethod');
- Checks that the
Userclasspath is valid. - Checks that the
UserPolicyclasspath is valid. - Checks that
someMethodexists.
php artisan check:dynamic_where
Looks for "dynamic where" methods like whereFamilyName('...') and suggests where('family_name', '...').
php artisan enforce:query
Calls the static query method on your Eloquent query chains so IDEs can understand Eloquent. For example, converts User::where(... into User::query()->where(....
php artisan check:dead_controllers
Finds controllers with no routes pointing to them.
php artisan check:generic_docblocks
php artisan check:generic_docblocks {--folder=app/Models} {--file=SomeFile.php}
Removes Laravel's default doc-blocks. Use --folder=, --file=, --except-file, or --except-folder to narrow down the scanned folders.
php artisan enforce:helper_functions
php artisan enforce:helper_functions {--folder=app/Models} {--file=SomeFile.php}
Converts Laravel facade calls into helper functions. Use --folder=, --file=, --except-file, or --except-folder to narrow down the scanned folders.
php artisan list:models
php artisan list:models {--folder=app/Models}
Searches the project and lists the model classes. Use --folder= to narrow down the scanned folders.
php artisan check:extra_fqcn
php artisan check:extra_fqcn {--folder=app/Models} --fix {--class=ClassRefsToBeFixed}
Searches for unnecessary fully qualified class names (FQCN) that are already imported at the top. Use --class= to only fix references to a specific class.
And more features will be added soon. ;)
Credits
License
The MIT License (MIT). Please see the License File for more information.
🙋 Contributing
If you find an issue or have a better way to do something, feel free to open an issue or a pull request. If you use laravel-microscope in your open-source project, create a pull request to provide its URL as a sample application in the README.md file.
❗ Security
If you discover any security-related issues, please email imanghafoori1@gmail.com instead of using the issue tracker.
More From The Author
Laravel HeyMan
💎 It allows us to write expressive code to authorize, validate, and authenticate.
A man will never fail unless he stops trying.
— Albert Einstein
❤️ Contributors
This project exists thanks to all the people who contribute. [Contributors].
