Convert Figma logo to code with AI

imanghafoori1 logolaravel-microscope

Fearless refactoring, it does a lot of smart checks to find certain errors.

1,465
97
1,465
10

Top Related Projects

⚗️ Adds code analysis to Laravel improving developer productivity and code quality.

PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.

12,802

PHP Static Analysis Tool - discover bugs in your code without running it!

5,537

A static analysis tool for finding errors in PHP applications

A tool to automatically fix PHP Coding Standards issues

Quick Overview

The laravel-microscope package is a powerful tool for Laravel developers that helps identify and fix common code issues, improve code quality, and enhance the overall development experience. It provides a comprehensive set of checks and analyses to help developers identify and address various code-related problems.

Pros

  • Comprehensive Code Analysis: The package offers a wide range of checks and analyses, covering various aspects of Laravel development, such as code style, security, performance, and best practices.
  • Improved Code Quality: By identifying and addressing code issues early in the development process, the package helps maintain a high level of code quality and reduces technical debt.
  • Enhanced Developer Productivity: The package's automated checks and suggestions can save developers time and effort, allowing them to focus on more important tasks.
  • Customizable Configuration: The package allows developers to customize the checks and analyses to fit their specific project requirements, making it more flexible and adaptable.

Cons

  • Potential Performance Impact: Depending on the size and complexity of the project, the package's analysis process may have a slight performance impact, especially during the initial run.
  • Learning Curve: Developers may need to spend some time understanding the package's features and configuration options to fully utilize its capabilities.
  • Dependency on Laravel: The package is tightly integrated with the Laravel framework, which means it may not be suitable for non-Laravel projects.
  • Limited Community Support: While the package has a decent number of contributors, the overall community support may be smaller compared to more widely-used Laravel packages.

Code Examples

Here are a few examples of how to use the laravel-microscope package:

  1. Running the Analysis:
php artisan microscope:run

This command will run the entire set of checks and analyses on the project.

  1. Checking for Unused Imports:
php artisan microscope:unused-imports

This command will identify any unused imports in the project, helping to keep the codebase clean and organized.

  1. Checking for Unused Variables:
php artisan microscope:unused-variables

This command will identify any unused variables in the project, which can help improve code readability and maintainability.

  1. Checking for Duplicate Code:
php artisan microscope:duplicate-code

This command will identify any duplicate code in the project, which can help reduce technical debt and improve the overall codebase.

Getting Started

To get started with the laravel-microscope package, follow these steps:

  1. Install the package using Composer:
composer require imanghafoori1/laravel-microscope --dev
  1. Publish the package's configuration file:
php artisan vendor:publish --provider="Imanghafoori\LaravelMicroscope\LaravelMicroscopeServiceProvider"
  1. Customize the configuration file (config/microscope.php) to fit your project's needs, such as enabling or disabling specific checks, setting up custom rules, and more.

  2. Run the analysis using the following command:

php artisan microscope:run
  1. Review the analysis results and address any issues or concerns identified by the package.

  2. (Optional) Integrate the package into your continuous integration (CI) workflow to ensure code quality is maintained throughout the development process.

Competitor Comparisons

⚗️ Adds code analysis to Laravel improving developer productivity and code quality.

Pros of Larastan

  • Built on top of PHPStan, providing a more robust and mature static analysis foundation
  • Offers more comprehensive type checking and inference capabilities
  • Integrates seamlessly with Laravel-specific features and conventions

Cons of Larastan

  • Requires more configuration and setup compared to Laravel Microscope
  • May have a steeper learning curve for developers new to static analysis tools
  • Can be slower to run on large codebases due to its comprehensive analysis

Code Comparison

Laravel Microscope:

use Imanghafoori\LaravelMicroscope\Analyzers\ClassMethods;

$methods = ClassMethods::read($classFilePath);

Larastan:

// phpstan.neon
parameters:
    level: 5
    paths:
        - app
    ignoreErrors:
        - '#Access to an undefined property#'

Laravel Microscope focuses on quick, Laravel-specific checks, while Larastan provides more thorough static analysis based on PHPStan. Laravel Microscope is easier to set up and use out of the box, but Larastan offers more comprehensive analysis at the cost of additional configuration and potentially longer run times.

PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.

Pros of PHP_CodeSniffer

  • Language-agnostic: Works with PHP, JavaScript, and CSS
  • Extensive ruleset: Includes a wide range of coding standards (PSR-1, PSR-2, PSR-12, etc.)
  • Customizable: Allows creation of custom rulesets and sniffs

Cons of PHP_CodeSniffer

  • Not Laravel-specific: Lacks specialized checks for Laravel framework
  • Performance: Can be slower on large codebases compared to Laravel Microscope
  • Learning curve: Requires more setup and configuration

Code Comparison

PHP_CodeSniffer:

<?php
phpcs --standard=PSR12 /path/to/code

Laravel Microscope:

<?php
php artisan microscope:check

PHP_CodeSniffer is a versatile tool for checking coding standards across multiple languages, while Laravel Microscope is tailored specifically for Laravel applications. PHP_CodeSniffer offers more extensive rulesets and customization options but may require more setup. Laravel Microscope provides out-of-the-box Laravel-specific checks and potentially better performance for Laravel projects. The choice between the two depends on the project's needs, with PHP_CodeSniffer being more suitable for multi-language projects and Laravel Microscope being ideal for Laravel-focused development.

12,802

PHP Static Analysis Tool - discover bugs in your code without running it!

Pros of PHPStan

  • Language-agnostic static analysis tool, not limited to Laravel applications
  • More extensive rule set and customization options
  • Larger community and ecosystem with extensions and plugins

Cons of PHPStan

  • Steeper learning curve and more complex configuration
  • May require more setup time for Laravel-specific projects
  • Can be slower for large codebases due to its comprehensive analysis

Code Comparison

Laravel Microscope:

use Imanghafoori\LaravelMicroscope\Analyzers\ClassMethods;

$methods = ClassMethods::read($classFilePath);

PHPStan:

use PHPStan\Analyser\Analyser;

$analyserResult = $analyser->analyseFiles([$filePath]);

Summary

Laravel Microscope is tailored for Laravel applications, offering quick setup and Laravel-specific checks. PHPStan provides a more comprehensive static analysis tool for PHP projects in general, with greater flexibility and a larger ecosystem. Laravel Microscope may be more suitable for Laravel-focused developers seeking quick insights, while PHPStan is better for teams requiring in-depth analysis across various PHP projects.

5,537

A static analysis tool for finding errors in PHP applications

Pros of Psalm

  • Supports multiple programming languages, not limited to PHP or Laravel
  • More comprehensive static analysis with a wider range of checks
  • Integrates with various IDEs and CI tools

Cons of Psalm

  • Steeper learning curve due to more complex configuration options
  • May produce more false positives, requiring fine-tuning
  • Not specifically tailored for Laravel projects

Code Comparison

Laravel Microscope:

use Imanghafoori\LaravelMicroscope\Analyzers\ClassMethods;

$methods = ClassMethods::read($classFilePath);

Psalm:

use Psalm\Config;
use Psalm\Context;

$config = Config::loadFromXMLFile($configPath);
$context = new Context();

Key Differences

  • Laravel Microscope focuses on Laravel-specific checks and optimizations
  • Psalm offers more general-purpose static analysis for PHP projects
  • Laravel Microscope has a simpler setup process for Laravel applications
  • Psalm provides more detailed type inference and analysis

Use Cases

  • Choose Laravel Microscope for Laravel-specific projects requiring quick setup
  • Opt for Psalm for larger, more complex PHP projects needing thorough analysis

Community and Support

  • Laravel Microscope has a growing community within the Laravel ecosystem
  • Psalm has a larger, more established user base across various PHP projects

A tool to automatically fix PHP Coding Standards issues

Pros of PHP-CS-Fixer

  • Broader scope: Works with any PHP project, not limited to Laravel applications
  • More extensive ruleset: Offers a wide range of coding style and formatting rules
  • Active community: Larger user base and more frequent updates

Cons of PHP-CS-Fixer

  • Steeper learning curve: Requires more configuration and understanding of rules
  • Less focus on performance: Primarily targets coding style rather than optimizing code efficiency
  • Not tailored for Laravel: Lacks specific features for Laravel framework conventions

Code Comparison

Laravel Microscope:

use Imanghafoori\LaravelMicroscope\Analyzers\ClassMethods;

$methods = ClassMethods::read($classFilePath);

PHP-CS-Fixer:

use PhpCsFixer\Finder;
use PhpCsFixer\Config;

$finder = Finder::create()->in(__DIR__);
$config = (new Config())->setFinder($finder);

Laravel Microscope focuses on analyzing Laravel-specific code structures, while PHP-CS-Fixer provides a more general approach to PHP code styling and formatting. Laravel Microscope is better suited for Laravel developers looking to optimize their applications, whereas PHP-CS-Fixer is a versatile tool for maintaining consistent coding standards across various PHP projects.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Find Bugs Before They Bite

microscope_header

Built with :heart: for lazy Laravel developers ;)

Why repeat the old errors, if there are so many new errors to commit?

(Bertrand Russel)

Give your eyes a rest, we will detect and fix them for you.

Packagist Stars Required Laravel Version Required PHP Version Latest Version on Packagist Quality Score Total Downloads Today Downloads tests Imports

Key things to know:

  • It is created to be smarter than phpstorm and other IDEs in finding errors.
  • It is created to understand laravel run-time and magic.
  • It does not show you stupid false errors, all the reported cases are really errors.
  • 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 performance possible.

:film_strip: Video tutorial here

:star: 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.

Stargazers

⬇️ Installation

You can install the package via Composer:

composer require imanghafoori/laravel-microscope --dev

You may also publish config file:

php artisan vendor:publish --provider="Imanghafoori\LaravelMicroscope\LaravelMicroscopeServiceProvider"

💎 Usage:

Useful Commands:

You can run :point_down:

#Artisan Command
1php artisan search_replace
2php artisan check:early_returns
3php artisan check:all

Less Used Commands:

#Artisan Command
1php artisan check:views
2php artisan check:routes
3php artisan check:psr4 {-s|--nofix}
4php artisan check:imports {-s|--nofix} {--wrong} {--extra}
5php artisan check:stringy_classes
6php artisan check:dd
7php artisan check:bad_practices
8php artisan check:compact
9php artisan check:blade_queries
10php artisan check:action_comments
11php artisan check:extract_blades
12php artisan pp:route
13php artisan check:generate
14php artisan check:endif
15php artisan check:events
16php artisan check:gates
17php artisan check:dynamic_where
18php artisan check:aliases
19php artisan check:dead_controllers
20php artisan check:generic_docblocks
21php artisan enforce:helper_functions
22php artisan list:models

Global Helper Functions:

Also, You will have access to some global helper functions

microscope_dd_listeners($event);

In case you wonder what the listeners are and where they are, you can call microscope_dd_listeners(MyEvent::class); within either the boot or register methods. It works like a normal dd(...); meaning that the program stops running at that point.

📖 What do the Commands do?

Let's start with the:

php artisan search_replace {--name=pattern_name} {--tag=some_tag} {--file=partial_file_name} {--folder=partial_folder_name}

This is a smart and very powerful search/replace functionality that can be a real "time saver" for you.

:one: Defining patterns:

If you run the command artisan search_replace for the first time, it will create a search_replace.php file in the project's root. Then, you can define your patterns, within that file.

Examples:

Let's define a pattern to 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' => [...],
    ]
];
  • Here the key optional_to_nullsafe is the "unique name" of your pattern. (You can target your pattern by running php artisan search_replace --name=optional_to_nullsafe)
  • The search pattern has a "<in_between>" placeholder which captures everything in between the pair of parenthesis.
  • In the replace block we substitute what we have captured by the first placeholder with the "<1>". If we have more placeholders, we could have had "<2>" etc.
  • In the tag block we can mention some tags as an array of strings or a string separated by commas and target them by --tag flag: php artisan search_replace --tag=php8

:two: Placeholders:

Here is a comprehensive list of placeholders you can use:

#PlaceholdersDescription
1<var> or <variable>for variables like: $user
2<str> or <string>for hard coded strings: 'hello' or "hello"
3<class_ref>for class references: \App\User::where(... , User::where
4<full_class_ref>only for full references: \App\User::
5<until>to capture all the code until you reach a certain character.
6<comment>for comments (it does not capture doc-blocks beginning with: /** )
7<doc_block>for php doc-blocks
8<statement>to capture a whole php statement.
9<name:nam1,nam2> or <name>for method or function names. ->where or ::where
10<white_space>for whitespace blocks
11<bool> or <boolean>for true or false (acts case-insensetive)
12<number>for numeric values
13<cast>for type-casts like: (array) $a;
14<int> or "<integer>"for integer values
15<visibility>for public, protected, private
16<float>for floating point number
17"<global_func_call:func1,func2>"to detect global function calls
18<in_between>to capture code within a pair of {...} or (...) or [...]
19<any>captures any token.

You can also define your own keywords if needed!

You just define a class for your new keyword and append the class path to the end of the Finder::$keywords[] = MyKeyword::class property. Just like the default keywords.

Example:

:one: Let's say you want to find only the "comments" which contain the word "todo:" in them.

 '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;
        },
]

Note If you do not mention the 'replace' key it only searches and reports them to you.

:two: 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

:three: Mutator: In mutators, you are free to manipulate the $matched values as much as you need to before replacing them in the results. You can also mention a static method instead of a function, like this: [MyClass::class, 'myStaticMethod']

:three: Let's say you want to put the optional comma for the Lets elements in the arrays if they are missing.

    'enforce_optional_comma' => [
        'search' => '<white_space>?]',
        'replace' => ',"<1>"]',
        'avoid_syntax_errors' => true,
        'avoid_result_in' => [
           ',,]',
           '[,]',
           '<var>[,]'
       ],
    ]

In this case, our pattern is not very accurate and in some cases, it may result in syntax errors. Because of that, we turn on the php syntax validator to check the result, but that costs us a performance penalty!!! To exclude the usage of PHP, to validate the results we have mentioned the avoid_result_in so that if they happen in the result it skips.

  • Note: The ? in the "<white_space>?" notes this is an optional placeholder.

If you are curious to see a better pattern that does not need any syntax checking, try this:

'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>]'
       ]
],

This is more complex but works much faster. (since it does not need the php syntax validator)

  • Here 'post_replace' is a pattern that is applied only and only on the resulting code to refine it, and NOT on the entire file.

  • You can optionally comment your placeholders (as above <1:any>) with numbers so that you know which one corresponds to which when replaced.

:four: Filters:

Currently, the microscope offers only two built-in filters: is_sub_class_of and in_array

Can you guess what the heck this pattern is doing?!

 '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'
          ]
      ]
  ]

It converts these:

User::where(...)->get();

\App\Models\User::find(...);

Into these:

User::query()->where(...)->get();

\App\Models\User::query()->find(...);
  • The filters here ensure that the captured class reference is a laravel Model and the method name is one of the names mentioned in the list.

So it does not tamper with something like this:

User::all();            // The `all` method can not be preceded with `query`

UserRepo::where(...);   /// UserRepo is not a model
  • This is something which you can never do by regex.

:five: Capturing php "statements":

Let's say we want to opt into php 7.4 arrow functions:

'fn' => [
    'search' => 'function (<in_between>)<until>{ <statement> }',
    'replace' => 'fn (<1>) => <3>',
    'tags' => 'php74,refactor',
    'mutator' => function ($matches) {
      $matches[2][1] = str_replace(['return ', ';'], '', $matches[2][1]);

      return $matches;
    }
]

In this example, we have mentioned one single "statement" in the body of the function. So if it encounters a function with two or more statements it will ignore that.

$closure = function ($a) use ($b) {
    return $a + $b;
};

// will become:
$closure = fn($a) => $a + $hello;

But this is not captured:

$closure = function ($a) {
    $a++;
    return $a + $b;
};

:six: Difference between <statement> and <until>;

They seem to be very similar but there is an important case in which you can not use <until>; to cover it properly!

$first = $a + $b;

$second = function ($a) {
    $a++;

    return $a;
};

If we define our pattern like this:

return [
    'staty' => [
        'search' => '<var> = <until>;',   
    ]
];

For $c = $a + $b; they act the same way, but for the second one "<until>"; will not capture the whole closure and will stop as soon as it reaches $a++; and that is a problem.

But if you define your pattern as: '<var> = <statement>' it would be smart enough to capture the correct semicolon at the end of closure definition and whole close would be captured.

:seven: Capturing global function calls:

Let's say you want to eliminate all the dd(...) or dump(...) before pushing to production.

return [
    'remove_dd' => [
        'search' =>  "'<global_func_call:dd,dump>'('<in_between>');", 
        'replace' => ''
    ]
];

This will NOT capture cases like below:

$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);
    

:eight: Repeating patterns:

Let's say we want to refactor:

User:where('name', 'John')->where('family', 'Dou')->where('age', 20)->get();

into:

User:where([
    'name' => 'John',
    'family' => 'Dou',
    'age'=> 20,
])->get();

Ok, how the pattern would look like then?!

"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 yeah??!

Possibilities are endless and the sky is the limit...

php artisan check:early_returns

This will scan all your Psr-4 loaded classes and flattens your functions and loops by applying the early return rule. For example:

<?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
}

Will be discovered and converted into:

<?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
}

The same thing will apply for functions and methods, but with return

<?php

if ($cond1) {
    if ($cond2) {
        ....       
    }
}

// we get merged into:

if ($cond1 && $cond2) { 
    ...  
}

  • It also supports the ruby-like if():/endif; syntax;
<?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';

Although this type of refactoring is safe and is guaranteed to do the same thing as before, be careful to commit everything before trying this feature, in case of a weird bug or something.

php artisan check:psr4

  • It checks for all the psr4 autoload defined in the composer.json file and goes through all the classes to have the right namespace, according to PSR-4 standard.
  • It automatically corrects namespaces (according to PSR-4 rules)
  • It also checks for references to the old namespace with the system and replaces them with the new one.

php artisan check:generate

You make an empty file, and we fill it, based on naming conventions.

If you create an empty .php file which ends with ServiceProvider.php after running this command: 1 - It will be filled with a boilerplate and correct Psr-4 namespace. 2 - It will be appended to the providers array in the config/app.php

php artisan check:imports

  • It checks all the imports (use statements) to be valid and reports invalid ones.
  • It autocorrects some references, no ambiguity is around the class name.
  • It can understand the laravel aliased classes so use Request; would be valid.

php artisan check:bad_practices

  • It detects bad practices like env() calls outside the config files.

php artisan check:routes

  • It checks that your routes refer to valid controller classes and methods.
  • It checks all the controller methods to have valid type-hints.
  • It scans for route(), redirect()->route(), \Redirect::route() to refer to valid routes.
  • It will report the public methods of controllers, which have no routes pointing to them. In other words dead controllers are detected.

php artisan check:compact

  • In php 7.3 if you "compact" a non-existent variable you will get an error, so this command checks the entire project for wrong compact() calls and reports to you, which parameters should be removed.

php artisan check:blade_queries

  • Blade files should not contain DB queries. We should move them back into controllers and pass variables. This command searches all the blade files for the Eloquent models and DB query builder and shows them if any.

php artisan check:extract_blades

  • If you want to extract a blade partial out and make it included like: @include('myPartials.someFile')

You can use {!! extractBlade('myPartials.someFile') !!} in your blade files to indicate start/end line and the path/name of the partial you intend to be made.

 <html>
      
      {!! extractBlade('myPartials.head') !!}
          <head>...</head>
      {!! extractBlade() !!}

      
      {!! extractBlade('myPartials.body') !!}
          <body>...</body>
      {!! extractBlade() !!}
      
 </html>

After you execute php artisan check:extract_blades it will become:

<html>
    @include('myPartials.head')
    @include('myPartials.body')
</html>

Also, it will create:

  • resources/views/myPartials/head.blade.php
  • resources/views/myPartials/body.blade.php

And put the corresponding content in them.

  • It is also compatible with namespaced views in modular Laravel applications. So this syntax will work: 'MyMod::myPartials.body'

php artisan check:action_comments {--file=SomeFile.php}

  • This adds annotations in the controller actions so that you know which route is pointing to the current controller action.
  • You can use the --file= option to narrow down the scanned files.

php artisan pp:route

  • First, you have to put this in your route file: microscope_pretty_print_route('my.route.name');
  • You can also pass the Controller@method syntax to the function.
  • You can call it multiple times to pretty-print multiple routes.

php artisan check:views

  • It scans your code and finds the view() and View::make() and reports if they refer to the wrong files.
  • It scans your blade files for @include() and @extends() and reports if they refer to the wrong files.

Also, it can detect unused variables which are passed into your view from the controller like this: view('hello', [...]); For that you must open up the page in the browser and then visit the log file to see a message like this:

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');

Remember some variables are passed into your view from a view composer and not the controller. Those variables are also taken into consideration when detecting unused variables.

php artisan check:events

For example, consider:

Event::listen(MyEvent::class, '\App\Listeners\MyListener@myMethod');

1 - It checks the \App\Listeners\MyListener classpath to be valid.

2 - It checks the myMethod method to exist on the MyListener class

3 - It checks the myMethod method to have the right type-hint (if any) in its signature, for example:

public function myMethod(OtherEvent $e) // <---- notice type-hint here
{
    //
}

This is a valid but wrong type-hint, and will be reported to you. Very cool, isn't it ??!

  • Note that it does not matter how you are setting your event listener,

1- in the EventServiceProvider,

2- By Event::listen facade,

3- By Subscriber class... or any other way. The error would be found. :)

php artisan check:gates

It checks the validity of all the gates you have defined, making sure that they refer to a valid class and method.

It also checks for the policy definitions to be valid.

Gate::policy(User::class, 'UserPolicy@someMethod');
Gate::define('someAbility', 'UserGate@someMethod');

1 - It checks the User classpath to be valid.

2 - It checks the UserPolicy classpath to be valid.

3 - It checks the someMethod method to exist.

php artisan check:dynamic_where

  • It looks for "dynamic where" methods like whereFamilyName('...') with where('family_name', '...').

php artisan enforce:query

  • It calls the static query method on your eloquent query chains so that IDEs can understand eloquent.

  • For example, converts: User::where(... to User::query()->where(...

php artisan check:dead_controllers

  • We can find the controllers that don't have any routes.

php artisan check:generic_docblocks {--folder=app/Models} {--file=SomeFile.php}

  • Removes Laravel's DocBlocks.
  • You can use --folder= or --file= option to narrow down the scanned folders.

php artisan enforce:helper_functions {--folder=app/Models} {--file=SomeFile.php}

  • Converting Laravel facade into helper functions.
  • You can use --folder= or --file= option to narrow down the scanned folders.

php artisan list:models {--folder=app/Models}

  • It searches the project and lists the model classes.
  • You can use --folder= option to narrow down the scanned folders.

And more features will be added soon. ;)

Credits

License

The MIT License (MIT). Please see License File for more information.

:raising_hand: 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.

:exclamation: 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

:gem: It allows us to write expressive code to authorize, validate, and authenticate.


Laravel Terminator

:gem: A minimal yet powerful package which allows you to refactor your controllers.

Laravel AnyPass

:gem: It allows you to login with any password in the local environment only.

A man will never fail unless he stops trying.

Albert Einstein

❤️ Contributors

This project exists thanks to all the people who contribute. [Contributors].

⭐ Star History

Star History Chart