swissspidy/phpstan-no-private
PHPStan extension that reports deprecation warnings when code uses “pseudo-private” elements marked with @access private. Helps prevent relying on internal classes, methods, functions, or properties. Easy install via Composer with optional extension-installer support.
The swissspidy/phpstan-no-private package aligns well with Laravel’s dependency injection (DI) principles and explicit encapsulation patterns. It enforces stricter visibility rules by treating @access private-annotated elements as deprecated, which complements Laravel’s:
Key Synergies:
protected vs. private: The package’s focus on @access private (not protected) avoids conflicts with Laravel’s common use of protected for internal class methods.laravel-pint, pestphp/pest) to enforce consistency.$fillable) are common but may violate the rule. Workarounds:
protected instead of private.@access public or @ignore in PHPStan config.| Risk Area | Severity | Mitigation Strategy |
|---|---|---|
| PHPStan 2.0 Breaking Change | High | Test locally before CI/CD adoption; document upgrade steps. |
| False Positives | Medium | Use phpstan.neon exclusions or @ignore annotations. |
| Refactoring Overhead | High | Phase adoption (start with new code); use --generate-baseline. |
| CI/CD Pipeline Impact | Medium | Cache PHPStan results to reduce build time. |
| Third-Party Packages | Low | Ignore vendor directories in PHPStan config. |
Codebase Maturity:
Tooling Stack:
Team Readiness:
Customization Needs:
@access private vs. @deprecated)?Performance:
| Laravel Component | Fit Level | Notes |
|---|---|---|
| Service Container | High | Encourages DI over private property access. |
| Eloquent Models | Medium | Private properties (e.g., $fillable) may need refactoring. |
| Controllers | High | Private methods called from routes will trigger violations. |
| Jobs/Commands | High | Aligns with Laravel’s explicit dependency patterns. |
| Packages | Low | Third-party packages may require exclusions. |
Preparation Phase:
phpstan analyse --generate-baseline to identify violations.composer require --dev phpstan/phpstan:^2.0
# phpstan.neon
includes:
- vendor/swissspidy/phpstan-no-private/extension.neon
parameters:
level: 8 # Start with Level 8 (strict) to avoid false positives
Pilot Phase:
pathExclusionFilters).Full Adoption:
# .github/workflows/phpstan.yml
- name: PHPStan
run: vendor/bin/phpstan analyse --level=max --error-format=github
composer.json scripts:
"scripts": {
"test": [
"phpstan"
]
}
phpstan --generate-baseline to suppress known issues temporarily.protected instead of private.private with protected (less strict but avoids violations)./** @ignore */
private function legacyMethod() { ... }
Phase 1: Configuration (1–2 days)
phpstan.neon to exclude non-critical paths.Phase 2: Pilot (2–4 weeks)
Phase 3: Full Rollout (4–8 weeks)
Phase 4: Enforcement (Ongoing)
@access private annotations in favor of protected or public APIs.CONTRIBUTING.md section on PHPStan rules.@access private vs. @ignore.phpstan --memory-limit=1G to avoid timeouts.vendor/ and node_modules/).| Failure Mode | Impact | Mitigation |
|---|---|---|
| CI/CD Blockers | High | Start with --error-level=5 (deprecated) before enforcing errors. |
| Refactoring Fatigue | Medium | Limit scope (e.g., new code only). |
| False Positives | Low | Use excludePaths or @ignore. |
| Tooling Rejection | High | Pilot with a small team first. |
| PHPStan Version Issues | Medium | Pin PHPStan version in composer.json. |
Training:
private → protected, getters/setters).Pilot Project:
How can I help you explore Laravel packages today?