PHPackages                             nette/phpstan-rules - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. nette/phpstan-rules

ActivePhpstan-extension[Utility &amp; Helpers](/categories/utility)

nette/phpstan-rules
===================

🐘 PHPStan rules and type extensions for Nette libraries

v1.0.5(3w ago)917.1k↓31.6%20BSD-3-ClausePHPPHP 8.1 - 8.5CI passing

Since Mar 28Pushed 3w ago2 watchersCompare

[ Source](https://github.com/nette/phpstan-rules)[ Packagist](https://packagist.org/packages/nette/phpstan-rules)[ Docs](https://nette.org)[ RSS](/packages/nette-phpstan-rules/feed)WikiDiscussions master Synced 2w ago

READMEChangelogDependencies (23)Versions (7)Used By (20)

PHPStan extensions for Nette libraries
======================================

[](#phpstan-extensions-for-nette-libraries)

[![Nette PHPStan Rules](https://private-user-images.githubusercontent.com/194960/547967352-c231ed47-a413-4dd2-81ef-83e52c080427.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODU1MTgzMDgsIm5iZiI6MTc4NTUxODAwOCwicGF0aCI6Ii8xOTQ5NjAvNTQ3OTY3MzUyLWMyMzFlZDQ3LWE0MTMtNGRkMi04MWVmLTgzZTUyYzA4MDQyNy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYwNzMxJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MDczMVQxNzEzMjhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT01ZDg3OTE4OTA1MzI0OTZhM2YzYzI3YjYwMTRiNWMxOGEwOTZlYzUyNjlkMmRlZjIwMDcxODQzMTk2ODA2YzhhJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZwbmcifQ.Rjh0RGPfMlLODDfpTyEElEjSHDOLvCuKqTjUZ9KbFiU)](https://private-user-images.githubusercontent.com/194960/547967352-c231ed47-a413-4dd2-81ef-83e52c080427.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODU1MTgzMDgsIm5iZiI6MTc4NTUxODAwOCwicGF0aCI6Ii8xOTQ5NjAvNTQ3OTY3MzUyLWMyMzFlZDQ3LWE0MTMtNGRkMi04MWVmLTgzZTUyYzA4MDQyNy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYwNzMxJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MDczMVQxNzEzMjhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT01ZDg3OTE4OTA1MzI0OTZhM2YzYzI3YjYwMTRiNWMxOGEwOTZlYzUyNjlkMmRlZjIwMDcxODQzMTk2ODA2YzhhJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZwbmcifQ.Rjh0RGPfMlLODDfpTyEElEjSHDOLvCuKqTjUZ9KbFiU)

[![Downloads this Month](https://camo.githubusercontent.com/e6905cb45ef90f24b5263b74d980decc6af80f0c9be6b92a0a1de331bc4294b7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646d2f6e657474652f7068707374616e2d72756c65732e737667)](https://packagist.org/packages/nette/phpstan-rules)[![Tests](https://github.com/nette/phpstan-rules/workflows/Tests/badge.svg?branch=master)](https://github.com/nette/phpstan-rules/actions)[![Latest Stable Version](https://camo.githubusercontent.com/47c9d45d0de7b623892e063d4babe5dbbe27aa8be6653f258e512f1dfdb6a794/68747470733a2f2f706f7365722e707567782e6f72672f6e657474652f7068707374616e2d72756c65732f762f737461626c65)](https://github.com/nette/phpstan-rules/releases)[![License](https://camo.githubusercontent.com/fa7d5fcf2c84b580327af52da95dd751703af65f079dc3c5a0081beac0789718/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4e65772532304253442d626c75652e737667)](https://github.com/nette/phpstan-rules/blob/master/license.md)

Makes [PHPStan](https://phpstan.org) smarter about Nette code. Install, and it just works — more precise types, fewer false positives.

[](#makes-phpstan-smarter-about-nette-code-install-and-it-just-works--more-precise-types-fewer-false-positives)

Installation
------------

[](#installation)

Install via Composer:

```
composer require --dev nette/phpstan-rules
```

Requirements: PHP 8.1 or higher and PHPStan 2.2.6+.

If you use [phpstan/extension-installer](https://github.com/phpstan/extension-installer), the extension is registered automatically. Otherwise add to your `phpstan.neon`:

```
includes:
    - vendor/nette/phpstan-rules/extension.neon
```

What's Included
---------------

[](#whats-included)

**Precise return types** — narrows return types of `Strings::match()`, `matchAll()`, `split()`, `Helpers::falseToNull()`, `Expect::array()`, `Arrays::invoke()`, and `Arrays::invokeMethod()` based on the arguments you pass. For `Strings::match()` and `matchAll()` with a constant pattern, the exact array shape is derived from the regular expression — e.g. `Strings::match($s, '#(\d+)-(\w+)#')` returns `array{string, string, string}|null` with one element per capture group (named groups included). The same shape is inferred for the `$matches` argument of a `Strings::replace()` callback. Also narrows `Container::getComponent()` and `$container['...']` to match the corresponding `createComponent*()` factory return type. For forms, `$form['name']` returns the specific control type (e.g. `TextInput`, `SelectBox`) based on the `addText()`, `addSelect()`, etc. call in the same function.

**Database row mapping** — narrows return types of `Explorer::table()`, `ActiveRow::related()`, `ActiveRow::ref()`, and `Selection::insert()` based on a configurable table-to-entity-class convention. For example, `$explorer->table('booking')` returns `Selection` instead of `Selection`, and a single-row `$bookings->insert([...])` returns `BookingRow` instead of the wide schema-dependent union. Configure via:

```
parameters:
    nette:
        database:
            mapping:
                tables:
                	*: App\Entity\*Row                    # * = PascalCase table name
                    special_table: App\Entity\SpecialRow  # optional explicit overrides
```

**Asset type narrowing** — narrows return types of `Registry::getMapper()` to the specific mapper class, and `Registry::getAsset()` / `tryGetAsset()` to the specific asset type (e.g. `ImageAsset`, `ScriptAsset`) based on file extension. Also narrows `FilesystemMapper::getAsset()` and `ViteMapper::getAsset()` directly. Configure via:

```
parameters:
    nette:
        assets:
            mapping:
                default: file                   # FilesystemMapper
                images: file                    # FilesystemMapper
                vite: vite                      # ViteMapper
                custom: App\MyMapper            # custom class (FQCN)
```

**Interface @property tags** — makes `@property-read`/`@property` annotations on interfaces work. PHPStan core ignores them there, so e.g. `$asset->url` on `Nette\Assets\Asset` reports `property.notFound`; with this extension the read gets the annotated type (nullsafe access included) and the false error is suppressed. Property writes are intentionally left unsupported.

**Html magic methods** — resolves `$html->getXxx()`, `setXxx()`, and `addXxx()` calls on `Nette\Utils\Html` that go through `__call()` but aren't declared via `@method` annotations.

**Runtime-validated callbacks** — `Nette\Utils\Callback::toReflection()` accepts any callback and escalates the validity check to a `ReflectionException` at runtime, so passing a value that can't be statically proven callable (typically a `[class-string, method-name]` tuple) no longer reports a false `argument.type` error.

**Removes `|false` and `|null` from PHP functions** — many native functions like `getcwd`, `json_encode`, `preg_split`, `preg_replace`, and [many more](extension-php.neon) include `false` or `null` in their return type even though these error values are unrealistic on modern systems. For `preg_*` functions this applies only to constant patterns. With the `u` modifier, `false` can also mean an invalid UTF-8 subject — this is stripped by design too, so that every regex call doesn't have to double as input validation. Validate untrusted input explicitly with `preg_match('##u', $s)`, whose `false` return type is preserved.

**Injected properties** — properties marked with the `#[Nette\DI\Attributes\Inject]` attribute are treated as initialized and written, so PHPStan won't report them as uninitialized or never written.

**Invalid regex detection** — reports invalid regular expression patterns passed to `Strings::match()`, `matchAll()`, `split()`, and `replace()`, so a malformed pattern is caught during analysis instead of at runtime.

**AbortException safety** — warns when a broad `catch (\Throwable)` or `catch (\Exception)` in a try block that calls `redirect()`, `forward()`, `terminate()`, etc. swallows `Nette\Application\AbortException` instead of rethrowing it — a mistake that silently breaks redirects.

**Subject narrowing after match** — inside `if (Strings::match($s, '#\d+#'))` the subject `$s` is narrowed (e.g. to `non-empty-string`) based on the pattern.

**Assert type narrowing** — PHPStan understands type guarantees after `Tester\Assert` calls like `notNull()`, `type()`, `true()`, etc.

**False positive suppression** — silences known PHPStan false positives in Nette patterns (arrow functions passed as `void` callbacks, runtime type validation closures, callbacks assigned to Form event-handler properties like `$onSuccess`, `$onClick`).

### Type Assertion Testing Helper

[](#type-assertion-testing-helper)

For Nette package developers: `TypeAssert` lets you verify type inference in tests using [Nette Tester](https://tester.nette.org):

```
use Nette\PHPStan\Tester\TypeAssert;

TypeAssert::assertTypes(__DIR__ . '/data/types.php');
TypeAssert::assertNoErrors(__DIR__ . '/data/clean.php');
```

The data file uses `assertType()` from PHPStan:

```
use function PHPStan\Testing\assertType;

assertType('non-empty-string', getcwd());
assertType('string', Normalizer::normalize('foo'));
```

[Support Me](https://github.com/sponsors/dg)
--------------------------------------------

[](#support-me)

Do you like Nette? Are you looking forward to the new features?

[![Buy me a coffee](https://camo.githubusercontent.com/afa7c20ccaac10ac4f1f51669bafb212856b932e0c8b276cb290336cf08624b8/68747470733a2f2f66696c65732e6e657474652e6f72672f69636f6e732f646f6e6174696f6e2d332e737667)](https://github.com/sponsors/dg)

Thank you!

###  Health Score

54

—

FairBetter than 97% of packages

Maintenance95

Actively maintained with recent releases

Popularity34

Limited adoption so far

Community22

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~24 days

Recently: every ~17 days

Total

6

Last Release

22d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/17f266513a3ca97500ec3d85d562b9279c7a6346358fe2b8d90390ece717a027?d=identicon)[david@grudl.com](/maintainers/david@grudl.com)

---

Top Contributors

[![dg](https://avatars.githubusercontent.com/u/194960?v=4)](https://github.com/dg "dg (39 commits)")

---

Tags

nettephpstan-extensionPHPStanstatic analysisnette

### Embed Badge

![Health badge](/badges/nette-phpstan-rules/health.svg)

```
[![Health](https://phpackages.com/badges/nette-phpstan-rules/health.svg)](https://phpackages.com/packages/nette-phpstan-rules)
```

###  Alternatives

[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.5k60.6M10.5k](/packages/larastan-larastan)[deptrac/deptrac

Deptrac is a static code analysis tool that helps to enforce rules for dependencies between software layers.

3.0k9.8M297](/packages/deptrac-deptrac)[shipmonk/dead-code-detector

Dead code detector to find unused PHP code via PHPStan extension. Can automatically remove dead PHP code. Supports libraries like Symfony, Doctrine, PHPUnit etc. Detects dead cycles. Can detect dead code that is tested.

5014.2M111](/packages/shipmonk-dead-code-detector)[phpstan/phpstan-doctrine

Doctrine extensions for PHPStan

67475.0M1.6k](/packages/phpstan-phpstan-doctrine)[phpstan/phpstan-symfony

Symfony Framework extensions and rules for PHPStan

79378.2M2.5k](/packages/phpstan-phpstan-symfony)[php-stubs/wordpress-stubs

WordPress function and class declaration stubs for static analysis.

20117.1M490](/packages/php-stubs-wordpress-stubs)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
