nunomaduro/phpinsights
PHP Insights analyzes PHP code quality, style, architecture, and complexity from your terminal. Works out of the box with Laravel (artisan insights), Symfony, Yii, Magento, and more, with built-in checks for reliability and loose coupling.
Installation:
composer require nunomaduro/phpinsights --dev
For Laravel projects, publish the config:
php artisan vendor:publish --provider="NunoMaduro\PhpInsights\Application\Adapters\Laravel\InsightsServiceProvider"
First Run:
./vendor/bin/phpinsights
Or in Laravel:
php artisan insights
Quick Wins:
--preset=laravel (or symfony, magento2, etc.) to skip framework-specific exclusions.--format=json to export results for CI/CD pipelines.Run a pre-commit hook or CI check to enforce code quality before merging:
#!/bin/bash
./vendor/bin/phpinsights --min-quality=80 || exit 1
This ensures no PR is merged with a quality score below 80.
Local Development:
Run php artisan insights after major refactors or PR reviews to catch architectural issues early.
Use --ide=vscode (or your IDE) for direct file navigation in terminal output.
Team Onboarding:
Share the phpinsights.php config as a team standard. Example:
return [
'preset' => 'laravel',
'exclude' => ['tests', 'migrations'],
'config' => [
\NunoMaduro\PhpInsights\Domain\Insights\Code\ForbiddenFunctionsSniff::class => [
'forbiddenFunctions' => ['dd', 'dump'],
],
],
];
CI Integration:
Add to .github/workflows/ci.yml:
- name: Run PHP Insights
run: ./vendor/bin/phpinsights --min-quality=85 --format=github
Laravel-Specific:
Override the default laravel preset to exclude app/Console/Kernel.php (commonly ignored):
'exclude' => [
'app/Console/Kernel.php',
],
Custom Insights:
Extend existing checks by creating a custom Insight class (see Contribution Guide). Example:
// app/Insights/Custom/NoHardcodedUrls.php
final class NoHardcodedUrls extends Insight {
public function hasIssue(): bool {
return (bool) $this->collector->getHardcodedUrls();
}
public function getTitle(): string {
return 'Hardcoded URLs found';
}
}
Then add it to phpinsights.php:
'add' => [
\NunoMaduro\PhpInsights\Domain\Metrics\Code\Strings::class => [
\App\Insights\Custom\NoHardcodedUrls::class,
],
],
IDE Links:
Configure phpinsights.php for your IDE:
'ide' => 'phpstorm', // or 'vscode', 'sublime', etc.
For custom IDEs (e.g., WebStorm), use:
'ide' => 'webstorm://open?file=%f&line=%l',
False Positives:
symfony/console ≥4.3 for IDE links to work. Upgrade via:
composer require symfony/console:^4.3
UnusedParameterSniff) may flag Laravel-specific patterns. Suppress them with:
/**
* @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter
*/
public function handle($request) {}
Performance:
vendor, node_modules) to speed up analysis.--cache (requires phpinsights ≥1.10).Laravel Quirks:
laravel preset excludes app/Providers/TelescopeServiceProvider.php. If you use Telescope, add it back:
'exclude' => [
'!app/Providers/TelescopeServiceProvider.php',
],
Verbose Output:
Run with -v to see insight class names for troubleshooting:
php artisan insights -v
Example output:
[Code] Unused parameter: \SlevomatCodingStandard\Sniffs\Functions\UnusedParameterSniff
Dry Run:
Use --dry-run to preview changes without applying fixes:
./vendor/bin/phpinsights --dry-run
Custom Presets:
Create a preset for your team’s stack. Example (config/phpinsights-team.php):
return [
'preset' => 'laravel',
'add' => [
\NunoMaduro\PhpInsights\Domain\Metrics\Classes::class => [
\App\Insights\Custom\NoHardcodedUrls::class,
],
],
'config' => [
\NunoMaduro\PhpInsights\Domain\Insights\Code\ForbiddenFunctionsSniff::class => [
'forbiddenFunctions' => ['dd', 'dump', 'abort_if'],
],
],
];
Then reference it in phpinsights.php:
'preset' => config_path('phpinsights-team.php'),
Formatter Extensions: Extend the default output by creating a custom formatter. Example:
// app/Formatters/CustomFormatter.php
use NunoMaduro\PhpInsights\Application\Console\Contracts\Formatter;
class CustomFormatter implements Formatter {
public function format(array $insights): string {
return "Custom: " . json_encode($insights);
}
}
Register it in phpinsights.php:
'formatter' => \App\Formatters\CustomFormatter::class,
PHPCS Sniffs:
Add custom PHPCS sniffs to phpinsights.php:
'add' => [
\NunoMaduro\PhpInsights\Domain\Metrics\Code\Comments::class => [
\Vendor\CustomSniff\MyCustomSniff::class,
],
];
github formatter to post insights as PR comments:
- name: PHP Insights
run: ./vendor/bin/phpinsights --format=github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
./vendor/bin/phpinsights --format=json | jq -r '.insights[] | "⚠️ \(.title): \(.description)"' | curl -X POST -H 'Content-type: text/plain' --data-binary @- SLACK_WEBHOOK_URL
./vendor/bin/phpstan analyse --level=max && ./vendor/bin/phpinsights
How can I help you explore Laravel packages today?