Major release focused on dramatically reducing false positives in
architectural / SOLID analysis on framework projects (Laravel and Symfony).
The headline change is that --type=laravel is now a real, opinionated preset
instead of a near-no-op flag.
(layer ⇒ namespace[] + suffix[]) lookup is replaced by an ordered list of
glob LayerRule objects (first match wins). array_merge_recursive is gone.
Custom ProjectTypeInterface implementations must implement the new
getLayerRules() method (defaults provided in AbstractProjectType).*Action is no longer classified as Controller in Laravel. It maps to
Application (use case). This eliminates ~12 spurious
"Infrastructure → Controller" violations on a typical Laravel app using the
Action pattern.Wiring is now a layer. ServiceProvider, container extensions and
files under **\\Providers\\** are flagged as Wiring, exempt from layer
violation reporting and from DIP scoring. Their job is precisely to bind
concrete classes from any layer, so the previous violations were noise.type_hint_param,
type_hint_return, and type_hint_property count toward the abstraction
ratio. extends, trait, new, static_call, instanceof, catch,
implements, const, use no longer pollute the metric. Old DIP scores
are not comparable.OrganizationController flagged with
104/104 concrete dependencies.ProjectTypeInterface gains 3 methods: getLayerRules(),
getDipIgnoreList(), getWiringPatterns(). AbstractProjectType provides
generic defaults so existing custom types still compile, but presets that
want framework-aware behaviour must override them.SolidAnalyzer::analyze() and ArchitectureAnalyzer::analyze() signatures
changed. SolidAnalyzer::analyze(array $fileResults, array $dipIgnoreList = [], array $wiringClasses = [], array $classIgnores = []); ArchitectureAnalyzer::analyze(array $fileResults, ?ProjectTypeInterface $projectType = null, ?ProjectConfig $config = null).ProjectAnalyzer constructor now requires ProjectConfigLoader and
BaselineManager. Symfony autowiring picks them up automatically.phpquality.json project configuration file at the project root.
Schema (all keys optional):
{
"layers": { "rules": [{ "match": "App\\Foo\\**", "layer": "Application" }] },
"wiring": { "patterns": ["**ServiceProvider"] },
"abstractionRatio": { "ignore": ["App\\Models\\**"] },
"ignore": { "violations": ["solid.dip:App\\Foo\\Bar"] },
"baseline": "phpquality.baseline.json"
}
layers.rules is prepended to the framework preset (project rules win).
wiring.patterns, abstractionRatio.ignore, ignore.violations are
unioned with framework defaults.[@phpquality-ignore](https://github.com/phpquality-ignore) docblock annotation on classes and interfaces:
/** [@phpquality-ignore](https://github.com/phpquality-ignore) solid.dip — wiring intentionnel */
final class FooService { … }
Codes: solid.srp, solid.dip, solid.isp, architecture.layer.--generate-baseline=phpquality.baseline.json writes a hash-keyed list of
all current violations and exits successfully (does not fail-on-violation).--baseline=phpquality.baseline.json filters violations whose hash is in
the baseline. The summary exposes suppressedByBaseline and warns about
obsoleteBaselineEntries (entries that no longer match anything →
regenerate).--config, --baseline, --generate-baseline.PhpQuality\Config\ProjectConfigLoader,
PhpQuality\Config\BaselineManager, PhpQuality\Config\ProjectConfig,
PhpQuality\Config\LayerRule,
PhpQuality\Analyzer\Ast\IgnoreAnnotationParser.Most users only need to run the new version: false positives drop on their own. If you previously had a CI policy on the violation counts, expect those counts to decrease.
If you have a custom ProjectTypeInterface implementation:
AbstractProjectType (gets the 3 new methods for free), ORgetLayerRules(), getDipIgnoreList(), getWiringPatterns().If you want to keep some violations in your reports while you migrate, pin
them via --generate-baseline and commit the baseline file. Subsequent runs
with --baseline=… will only show new violations.
CallstackTracer to capture controller informationDependencyTreeAnalyzer for static analysis of controller imports and dependenciesuse statements instead of all included filesconfig/packages/php_quality.yamlThresholdsConfig DTO for threshold management with framework defaults merging--wizard or -w option)amoifr/phpquality-bundle)--coverage option)--git-blame option)amoifr13/phpquality--user flag)How can I help you explore Laravel packages today?