Skip to content

Releases: hihaho/phpstan-rules

3.1.2

22 Apr 14:50
Immutable release. Only release title and notes can be modified.
4d47ab9

Choose a tag to compare

Internal performance work on rule hot paths — every optimisation is strictly a filter-order or data-structure change. No behaviour change, no public API change, no new or removed errors, no new configuration keys. All five rules remain final readonly class.

  • NoUnsafeRequestHelperRule — short-circuit the ReflectionProvider::hasFunction / getFunction pair with a strtolower($node->name->getLast()) !== 'request' pre-check. Reflection used to fire on every FuncCall in the configured namespaces; it now fires only on calls whose last name-segment could actually resolve to the global request() helper. Alias-aware: PHPStan's NameResolver already rewrites use function request as X imports to FullyQualified('request') before the rule runs, so X('key') still flags. Locked with a new use function request as req regression stub.
  • NoUnsafeRequestDataRulein_array(strtolower($method), $listOf22, true) replaced by isset($lookup[strtolower($method)]) against a flipped array<string, true> built once in the constructor. classIsRequest no longer reconstructs new ObjectType(Request::class) on every call; it reuses a single instance hoisted to a private readonly property.
  • NoUnsafeRequestFacadeRule — same isset-map treatment for unsafe methods; strtolower(Illuminate\Support\Facades\Request::class) hoisted to a private readonly property instead of recomputed per call; and the class-equality check (one string compare) now bails before the method-name lookup. Locked with a new use Illuminate\Support\Facades\Request as RequestFacade regression stub.
  • NoInvadeInAppCode$node->name->toString() is computed once into a local and reused across the two equality checks instead of being rebuilt twice.

Full Changelog: v3.1.1...v3.1.2

3.1.1

22 Apr 14:42
Immutable release. Only release title and notes can be modified.
0dac257

Choose a tag to compare

What's Changed

Full Changelog: v3.1.0...v3.1.1

3.1.0

21 Apr 16:31
Immutable release. Only release title and notes can be modified.
fe3434f

Choose a tag to compare

Added

  • Three rules preventing unvalidated reads from Illuminate\Http\Request in application code:
    • NoUnsafeRequestDataRule — flags MethodCall on a Request or FormRequest receiver whose method is in noUnsafeRequestData.unsafeMethods. Defaults: input, all, get, query, post, only, except, collect, string, str, integer, boolean, float, json, keys, fluent, array, date, enum, enums, file, allFiles. Union-typed receivers (Request|Other) are flagged when any member is-a Request. Scope-class exemption walks the inheritance chain — custom base FormRequest classes are transparent. Identifier: hihaho.validation.noUnsafeRequestData.
    • NoUnsafeRequestHelperRule — flags the request('key') direct-argument helper form. Uses PHPStan's ReflectionProvider to resolve imports and aliases (use function request as foo). Error message interpolates the literal key for grep-friendly triage. Zero-argument request() is not flagged — chained method calls on its return are caught by NoUnsafeRequestDataRule. Identifier: hihaho.validation.noUnsafeRequestHelper.
    • NoUnsafeRequestFacadeRule — flags static calls on Illuminate\Support\Facades\Request (e.g. Request::boolean('debug'), Request::file('attachment')). Identifier: hihaho.validation.noUnsafeRequestFacade.
  • noUnsafeRequestData configuration block with unsafeMethods, namespaces, and excludeNamespaces. excludeNamespaces defaults to App\Providers and App\Http\Responses — both areas receive raw Request via framework-dictated signatures (RateLimiter::for(...) closures, Fortify response contracts) with no FormRequest entry point. App\Http\Resources is intentionally not defaulted; add it in your own config if JsonResource::toArray(Request) reading raw request data is acceptable for your project.
  • ChecksNamespace::namespaceStartsWithAny() helper for list-based namespace matching.

Changed

  • Raw readers on a FormRequest typehint in a controller are now flagged. FormRequest auto-validation runs on dispatch, but inherited readers still return the full unvalidated payload including keys outside rules(). Use $request->validated(), $request->safe(), or the array returned by $request->validate([...]) instead. For Stringable / int / bool chaining, $request->safe()->string('key') mirrors $request->string('key') against validated input.

See README.md for full rule descriptions, configuration keys, and baseline categories.

Full Changelog: v3.0.0...v3.1.0

v3.0.0

12 Apr 15:09
Immutable release. Only release title and notes can be modified.
6a52fe6

Choose a tag to compare

Major version. Class-naming and routing conventions move to the sibling package hihaho/rector-rules as auto-fixers. This package keeps the rules that have no auto-fix counterpart. See UPGRADING.md for migration steps.

Removed

  • Rules\NamingClasses\Commands, Mail, Notifications, EloquentApiResources (and SuffixableRule base). Replaced by AddCommandSuffixRector, AddMailSuffixRector, AddNotificationSuffixRector, and AddResourceSuffixRector in hihaho/rector-rules.
  • Rules\Routing\SlashInUrl and Rules\Routing\RouteGroups. Replaced by NormalizeRoutePathRector and RouteGroupArrayToMethodsRector in hihaho/rector-rules.
  • PHP 8.2 support. Minimum is now ^8.3.
  • illuminate/{console,http,mail,notifications,routing} dev deps. Only illuminate/support remains in require.

Changed

  • ChainedNoDebugInNamespaceRule now narrows matches to methods declared by a class in the Illuminate\ namespace. A domain class with its own ->dump() method is no longer a false positive.
  • StaticChainedNoDebugInNamespaceRule narrows the same way, with a Facade subclass fallback so Cache::dump() and other facades without @method static ... dump() annotations still flag via the Facade::__callStatic proxy.
  • NoInvadeInAppCode identifier category corrected from hihaho.debug.* to hihaho.generic.* (not a debug rule).
  • All rules now use final readonly class, #[\Override] on interface implementations, and explicit @return list<IdentifierRuleError> annotations.
  • OnlyAllowFacadeAliasInBlade keeps \ReflectionClass runtime reflection deliberately. PHPStan's ReflectionProvider does not invoke SPL autoloaders, so static discovery would silently miss every lazy Laravel facade alias. Documented in-source.
  • extension.neon: rules shorthand for dependency-free rules, services: block only for the rule that needs ReflectionProvider injected.

Added

  • Laravel 13 coverage in the CI test matrix. illuminate/support: ^11.31 | ^12.0 | ^13.0 was already declared; the matrix now exercises all three.
  • Rule test coverage: 44 tests across 5 rule classes. Every rule has identifier assertions, dynamic-call-edge coverage, outside-App/Tests negative cases, and regression guards for the narrowing (unknown receiver, union types, user-defined facade, unannotated Laravel facade, non-Facade aliased class).
  • Rector setup: rector/rector ^2.0 dev dep, rector.php with php83 set, import-name cleanup, and composer rector, format, qa scripts.
  • package-boost + orchestra/testbench dev deps for managing .ai/skills/ and injecting the verification-before-completion guideline block into CLAUDE.md / AGENTS.md.
  • CHANGELOG.md backfilled to v0.1.0 in Keep-a-Changelog format, plus update-changelog.yml workflow that keeps it current on future releases.
  • Laravel-package README: badges, per-rule docs, and cross-link to hihaho/rector-rules.

CI

  • Merged rector.yml + fix-php-code-style-issues.yml into a single auto-fix.yml mutator (pull_request-only, same-repo PRs only).
  • New update-changelog.yml (runs on release publish).
  • analyzer.yml and tests.yml: path filters, concurrency with cancel-in-progress, per-tool result caching, 5-minute timeouts, matrix-injection hardening via env vars.
  • All third-party actions pinned to commit SHAs.

Quality configs

  • PHPStan: strictRules.allRules, 100% constant type coverage, PhpStorm editorUrl.
  • Pint aligned with hihaho/rector-rules sibling.
  • PHPUnit: beStrictAboutTestsThatDoNotTestAnything and a scoped <source> block.

What's Changed

Full Changelog: v2.2.0...v3.0.0

v2.2.0

01 Mar 16:13
Immutable release. Only release title and notes can be modified.
b427a51

Choose a tag to compare

What's Changed

Full Changelog: v2.1.0...v2.2.0

v2.1.0

26 Feb 11:45
57f8d4a

Choose a tag to compare

What's Changed

Full Changelog: v2.0.1...v2.1.0

v2.0.1

11 Dec 15:27
141e67c

Choose a tag to compare

What's Changed

  • Handle resource collections in rules/naming classes/eloquent api resources by @SanderMuller in #36

Full Changelog: v2.0.0...v2.0.1

v1.2.1

11 Dec 15:25

Choose a tag to compare

What's Changed

Handle resource collections in rules/naming classes/eloquent api resources by @SanderMuller in #36

Full Changelog: v1.2.0...v1.2.1

V1.2.0

11 Dec 14:01
2a16309

Choose a tag to compare

Backport v2 changes excluding PHPstan 2.0 to v1

v2.0.0

27 Nov 12:40
3ad3feb

Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v1.1.1...v2.0.0