povils/phpmnd
PHPMND detects magic numbers in PHP code to improve readability and maintainability. Flags numeric literals that should be constants (0 and 1 ignored by default). Install via Composer and run vendor/bin/phpmnd locally or globally in CI and dev workflows.
Installation
composer require --dev povils/phpmnd
Add to composer.json under require-dev to ensure it runs only in dev environments.
Basic Configuration
Add to composer.json under "scripts":
"scripts": {
"test": [
"@phpmnd",
"@phpunit"
]
}
This ensures phpmnd runs before PHPUnit in your test suite.
First Run Execute:
composer test
Review the output for detected magic numbers (e.g., hardcoded 2, 30, 0.5).
vendor/povils/phpmnd/config/defaults.php for built-in patterns (e.g., /\b(\d+)\b/).phpmnd.json (auto-generated on first run) or create a custom config file.phpmnd.json to exclude files/directories (e.g., vendor/, tests/).Run phpmnd in CI to fail builds with magic numbers, forcing developers to replace them with named constants (e.g., MAX_RETRIES = 3).
Pre-Commit Hook
Add to .git/hooks/pre-commit (or use husky):
./vendor/bin/phpmnd
Fail if magic numbers are detected.
CI Pipeline
Place phpmnd early in the pipeline (e.g., before linting):
# .github/workflows/ci.yml
- name: Check for magic numbers
run: composer test
IDE Integration
Use PHPStorm’s "Run External Tool" to execute phpmnd on file save (via vendor/bin/phpmnd path/to/file.php).
Extend Rules
Override phpmnd.json to add custom patterns:
{
"rules": [
{
"pattern": "/\\b([1-9]\\d{0,2}(?:\\.\\d+)?)m\\b/",
"message": "Hardcoded metric value found (e.g., '100m'). Use constants like `DISTANCE_KM`."
}
]
}
Contextual Exclusions Exclude specific files or regex-matching paths:
{
"exclude": [
"config/constants.php",
"src/Helpers/.*\\.php"
]
}
Severity Levels
Tag rules as error/warning in phpmnd.json to control CI behavior:
{
"rules": [
{
"pattern": "/\\b\\d+\\b/",
"severity": "error"
}
]
}
php-cs-fixer: Run phpmnd after php-cs-fixer to catch magic numbers introduced by auto-fixing.config/ and database/ from scans (they often contain hardcoded values intentionally).--path to scope scans to specific directories (e.g., composer test -- --path=src/App).False Positives
phpmnd may flag version numbers (e.g., 2.1.0) or timestamps./\b(\d+\.\d+\.\d+)\b/ → ignore).Performance
--parallel (if supported) or exclude non-critical directories.Overzealous Rules
0 as a flag)./\b0\b(?!\s*=>)/ to exclude 0 =>).Configuration Overrides
phpmnd.json may conflict with team defaults.--config to explicitly pass a config file:
composer test -- --config=phpmnd.team.json
Dry Run
Use --dry-run to preview changes without failing:
composer test -- --dry-run
Verbose Output Enable debug mode for detailed rule matching:
composer test -- --verbose
Test Custom Rules Validate rules with a test file:
echo "<?php \$x = 42;" > test_magic.php
./vendor/bin/phpmnd test_magic.php
Custom Exit Codes
Override exit codes in a script wrapper (e.g., phpmnd.sh):
#!/bin/bash
./vendor/bin/phpmnd || exit 1
Plugin System
Extend via Povils\Phpmnd\Rule\RuleInterface to create reusable rule sets (e.g., Laravel-specific constants).
GitHub Action
Use the povils/phpmnd-action for GitHub Actions:
- uses: povils/phpmnd-action@v1
with:
config: phpmnd.json
Config Files
Exclude config/ unless you’re enforcing magic numbers in config values (rare):
{
"exclude": ["config/"]
}
Migrations
Exclude database/migrations/ if using timestamps or IDs as magic numbers:
{
"exclude": ["database/migrations/"]
}
Service Providers
Watch for hardcoded array keys (e.g., ['status' => 1]). Replace with constants:
// Before
$user->status = 1;
// After
$user->status = User::STATUS_ACTIVE;
How can I help you explore Laravel packages today?