PHPackages                             cakedc/cakephp-phpstan - 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. cakedc/cakephp-phpstan

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

cakedc/cakephp-phpstan
======================

CakePHP plugin extension for PHPStan.

4.3.0(1mo ago)42837.4k↓19.4%720MITPHPPHP &gt;=8.1.0

Since May 24Pushed 1mo ago14 watchersCompare

[ Source](https://github.com/CakeDC/cakephp-phpstan)[ Packagist](https://packagist.org/packages/cakedc/cakephp-phpstan)[ RSS](/packages/cakedc-cakephp-phpstan/feed)WikiDiscussions 4.next-cake5 Synced 3d ago

READMEChangelog (10)Dependencies (14)Versions (24)Used By (20)

CakePHP extension for PHPStan
=============================

[](#cakephp-extension-for-phpstan)

[![Build Status](https://github.com/CakeDC/cakephp-phpstan/actions/workflows/ci.yml/badge.svg)](https://github.com/CakeDC/cakephp-phpstan/actions/workflows/ci.yml/badge.svg)[![Downloads](https://camo.githubusercontent.com/9c181fbb552e0faadf6341bc4caf450b72bf2c00be660e776587e397c790d1e7/68747470733a2f2f706f7365722e707567782e6f72672f43616b6544432f63616b657068702d7068707374616e2f642f746f74616c2e737667)](https://packagist.org/packages/CakeDC/cakephp-phpstan)[![Latest Version](https://camo.githubusercontent.com/b532ce06f812105398eb252545755c982b7d7da621728ace6f3cce9b406e371e/68747470733a2f2f706f7365722e707567782e6f72672f43616b6544432f63616b657068702d7068707374616e2f762f737461626c652e737667)](https://packagist.org/packages/CakeDC/cakephp-phpstan)[![License](https://camo.githubusercontent.com/2c2b55b6c214cb54a2d04a7208d3f6bfa5e7a22e290b90773859c5f3ce4637fd/68747470733a2f2f706f7365722e707567782e6f72672f43616b6544432f63616b657068702d7068707374616e2f6c6963656e73652e737667)](LICENSE.txt)

- [PHPStan](https://phpstan.org/)
- [CakePHP](https://cakephp.org/)

Provide services and rules for a better PHPStan analyze on CakePHP applications, includes services to resolve types (Table, Helpers, Behaviors, etc) and multiple rules.

Installation
============

[](#installation)

To use this extension, require it through [Composer](https://getcomposer.org/):

```
composer require --dev cakedc/cakephp-phpstan

```

If you also install [phpstan/extension-installer](https://github.com/phpstan/extension-installer), then you're all set!

 Manual installationIf you don't want to use `phpstan/extension-installer`, include `extension.neon` in your project's PHPStan config:

```
includes:
    - vendor/cakedc/cakephp-phpstan/extension.neon

```

General class load|fetch extensions
===================================

[](#general-class-loadfetch-extensions)

Features included:

1. Provide correct return type for `Cake\ORM\Locator\LocatorInterface::get()`
2. Provide correct return type for `Cake\Controller\Controller::loadComponent()`
3. Provide correct return type for `Cake\Controller\Controller::fetchTable()`
4. Provide correct return type for `Cake\Controller\Component::fetchTable()`
5. Provide correct return type for `Cake\Command\Command::fetchTable()`
6. Provide correct return type for `Cake\Mailer\Mailer::fetchTable()`
7. Provide correct return type for `Cake\View\Cell::fetchTable()`
8. Provide correct return type for `Cake\Console\ConsoleIo::helper()`

Table class return type extensions
==================================

[](#table-class-return-type-extensions)

### SelectQueryFindListReturnTypeExtension

[](#selectqueryfindlistreturntypeextension)

Provides proper return type for `find('list')->toArray()`:

1. Returns `array` for `find('list')->toArray()` instead of the generic entity array
2. Returns `array` when `groupField` is provided
3. Works with chained queries: `find('list')->where([...])->orderBy([...])->toArray()`

 Examples:```
  // PHPStan now knows the return type is array
  $roles = $this->Roles->find('list')->toArray();

  // PHPStan now knows the return type is array (chained)
  $roles = $this->Roles->find('list')->where(['active' => true])->orderBy(['name' => 'ASC'])->toArray();

  // PHPStan now knows the return type is array (grouped)
  $roles = $this->Roles->find('list', groupField: 'category_id')->toArray();
```

### TableEntityDynamicReturnTypeExtension

[](#tableentitydynamicreturntypeextension)

1. Provide correct return type for `Cake\ORM\Table::get` based on your table class name
2. Provide correct return type for `Cake\ORM\Table::newEntity` based on your table class name
3. Provide correct return type for `Cake\ORM\Table::newEntities` based on your table class name
4. Provide correct return type for `Cake\ORM\Table::newEmptyEntity` based on your table class name
5. Provide correct return type for `Cake\ORM\Table::findOrCreate` based on your table class name

 Examples:```
  //Now PHPStan know that \App\Models\Table\NotesTable::get returns \App\Model\Entity\Note
  $note = $this->Notes->get(1);
  $note->note = 'My new note';//No error

  //Now PHPStan know that \App\Models\Table\NotesTable::newEntity returns \App\Model\Entity\Note
  $note = $this->Notes->newEntity($data);
  $note->note = 'My new note new entity';//No error

  //Now PHPStan know that \App\Models\Table\NotesTable::newEmptyEntity returns \App\Model\Entity\Note
  $note = $this->Notes->newEmptyEntity($data);
  $note->note = 'My new note new empty entity';//No error

   //Now PHPStan know that \App\Models\Table\NotesTable::findOrCreate returns \App\Model\Entity\Note
  $note = $this->Notes->findOrCreate($data);
  $note->note = 'My entity found or created';//No error

  //Now PHPStan know that \App\Models\Table\NotesTable::newEntities returns \App\Model\Entity\Note[]
  $notes = $this->Notes->newEntities($data);
  foreach ($notes as $note) {
    $note->note = 'My new note';//No error
  }
```

### TableFirstArgIsTheReturnTypeExtension

[](#tablefirstargisthereturntypeextension)

1. Provide correct return type for `Cake\ORM\Table::patchEntity` based on the first argument passed
2. Provide correct return type for `Cake\ORM\Table::patchEntities` based on the first argument passed
3. Provide correct return type for `Cake\ORM\Table::save` based on the first argument passed
4. Provide correct return type for `Cake\ORM\Table::saveOrFail` based on the first argument passed
5. Provide correct return type for `Cake\ORM\Table::saveMany` based on the first argument passed
6. Provide correct return type for `Cake\ORM\Table::saveManyOrFail` based on the first argument passed
7. Provide correct return type for `Cake\ORM\Table::deleteMany` based on the first argument passed
8. Provide correct return type for `Cake\ORM\Table::deleteManyOrFail` based on the first argument passed
9. Provide correct return type for `Cake\ORM\Locator\LocatorAwareTrait::fetchTable` based on the first argument passed
10. Provide correct return type for `Cake\Mailer\MailerAwareTrait::getMailer` based on the first argument passed

 Examples:```
  //Now PHPStan know that \App\Models\Table\NotesTable::get returns \App\Model\Entity\Note
  $note = $this->Notes->get(1);
  $notes = $this->Notes->newEntities($data);

  //Since PHPStan knows the type of $note, these methods call use the same type as return type:
  $note = $this->Notes->patchEntity($note, $data);
  $text = $note->note;//No error.

  $note = $this->Notes->save($note);
  $text = $note->note;//No error.

  $note = $this->Notes->saveOrFail($note);
  $text = $note->note;//No error.
  //Since PHPStan knows the type of $notes, these methods call use the same type as return type:
  $notes = $this->Notes->patchEntities($notes);
  $notes = $this->Notes->saveMany($notes);
  $notes = $this->Notes->saveManyOrFail($notes);
  $notes = $this->Notes->deleteMany($notes);
  $notes = $this->Notes->deleteManyOrFail($notes);
```

Rules
=====

[](#rules)

All rules provided by this library are included in [rules.neon](rules.neon) and are enabled by default:

### AddAssociationExistsTableClassRule

[](#addassociationexiststableclassrule)

This rule check if the target association has a valid table class when calling to Table::belongsTo, Table::hasMany, Table::belongsToMany, Table::hasOne and AssociationCollection::load.

### AddAssociationMatchOptionsTypesRule

[](#addassociationmatchoptionstypesrule)

This rule check if association options are valid option types based on what each class expects. This cover calls to Table::belongsTo, Table::hasMany, Table::belongsToMany, Table::hasOne and AssociationCollection::load.

### AddBehaviorExistsClassRule

[](#addbehaviorexistsclassrule)

This rule check if the target behavior has a valid class when calling to Table::addBehavior and BehaviorRegistry::load.

### DisallowDebugFuncCallRule

[](#disallowdebugfunccallrule)

This rule disallow use of debug functions (`dd, debug, debug_print_backtrace, debug_zval_dump, pr, print_r, stacktrace, var_dump and var_export`).

The use of these functions in shipped code is discouraged because they can leak sensitive information or clutter output.

### DisallowDebugStaticCallRule

[](#disallowdebugstaticcallrule)

This rule disallow use of debug methods. The use of these methods in shipped code is discouraged because they can leak sensitive information or clutter output.

Methods covered:

```
- Cake\Error\Debugger::dump
- Cake\Error\Debugger::printVar
- DebugKit\DebugSql::sql
- DebugKit\DebugSql::sqld

```

### DisallowEntityArrayAccessRule

[](#disallowentityarrayaccessrule)

This rule disallow array access to entity in favor of object notation, is easier to detect a wrong property and to refactor code.

### GetMailerExistsClassRule

[](#getmailerexistsclassrule)

This rule check if the target mailer is a valid class when calling to Cake\\Mailer\\MailerAwareTrait::getMailer.

### LoadComponentExistsClassRule

[](#loadcomponentexistsclassrule)

This rule check if the target component has a valid class when calling to Controller::loadComponent and ComponentRegistry::load.

### OrmSelectQueryFindMatchOptionsTypesRule

[](#ormselectqueryfindmatchoptionstypesrule)

This rule check if the options (args) passed to Table::find and SelectQuery are valid find options types.

### TableGetMatchOptionsTypesRule

[](#tablegetmatchoptionstypesrule)

This rule check if the options (args) passed to Table::get are valid find options types.

### ControllerMethodMustBeUsedRule

[](#controllermethodmustbeusedrule)

This rule enforces that controller methods like `render()` and `redirect()` must be used (returned or assigned) to prevent unreachable code. These methods should not be called in void context - use them with a `return` statement or assign them to a variable to make the control flow explicit.

 Examples:```
// Bad - code after render() is unreachable
public function myAction()
{
    $this->render('edit');
    $this->set('data', 'value'); // This will never execute
}

// Good - explicit return prevents confusion
public function myAction()
{
    return $this->render('edit');
}

// Also good - assignment is valid
public function myAction()
{
    $response = $this->render('edit');

    return $response;
}

// Bad - code after redirect() is unreachable
public function myAction()
{
    $this->redirect(['action' => 'index']);
    $this->Flash->success('Done'); // This will never execute
}

// Good - explicit return prevents confusion
public function myAction()
{
    return $this->redirect(['action' => 'index']);
}
```

### How to disable a rule

[](#how-to-disable-a-rule)

Each rule has a parameter in cakeDC 'namespace' to enable or disable, it is the same name of the rule with first letter in lowercase. For example to disable the rule AddAssociationExistsTableClassRule you should have

```
parameters:
	cakeDC:
	 	addAssociationExistsTableClassRule: false

```

Configuration
=============

[](#configuration)

### Custom application namespace

[](#custom-application-namespace)

By default, this extension assumes your application uses the `App` namespace. If your application uses a custom namespace, configure it with the `appNamespace` parameter:

```
parameters:
    cakeDC:
        appNamespace: MyApp

```

This affects class resolution in rules and type extensions (e.g. `MyApp\Model\Table\UsersTable` instead of `App\Model\Table\UsersTable`).

PHPDoc Extensions
=================

[](#phpdoc-extensions)

### TableAssociationTypeNodeResolverExtension

[](#tableassociationtypenoderesolverextension)

Fix intersection association phpDoc to correct generic object type, ex:

Change `\Cake\ORM\Association\BelongsTo&\App\Model\Table\UsersTable` to `\Cake\ORM\Association\BelongsTo`

### Tips

[](#tips)

To make your life easier make sure to have `@mixin` and `@method` annotations in your table classes. The `@mixin` annotation will help phpstan know you are using methods from behavior, and `@method` annotations will allow it to know the correct return types for methods like `Table::get()`, `Table::newEntity()`.

You can easily update annotations with the plugin [IdeHelper](https://github.com/dereuromark/cakephp-ide-helper).

Support
-------

[](#support)

For bugs and feature requests, please use the [issues](https://github.com/CakeDC/cakephp-phpstan/issues) section of this repository.

Commercial support is also available, [contact us](https://www.cakedc.com/contact) for more information.

Contributing
------------

[](#contributing)

If you'd like to contribute new features, enhancements or bug fixes to the plugin, please read our [Contribution Guidelines](https://www.cakedc.com/contribution-guidelines) for detailed instructions.

###  Health Score

66

—

FairBetter than 99% of packages

Maintenance91

Actively maintained with recent releases

Popularity51

Moderate usage in the ecosystem

Community35

Small or concentrated contributor base

Maturity74

Established project with proven stability

 Bus Factor1

Top contributor holds 74.7% 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 ~136 days

Total

17

Last Release

44d ago

Major Versions

1.0.2 → 2.0.02021-11-02

2.0.1 → 3.0.02023-09-26

2.1.0 → 4.0.02024-11-11

PHP version history (2 changes)1.0.0PHP &gt;=7.2.0

3.0.0PHP &gt;=8.1.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/204531?v=4)[Cake Development Corporation](/maintainers/CakeDC)[@CakeDC](https://github.com/CakeDC)

---

Top Contributors

[![rochamarcelo](https://avatars.githubusercontent.com/u/850748?v=4)](https://github.com/rochamarcelo "rochamarcelo (207 commits)")[![dereuromark](https://avatars.githubusercontent.com/u/39854?v=4)](https://github.com/dereuromark "dereuromark (30 commits)")[![steinkel](https://avatars.githubusercontent.com/u/151761?v=4)](https://github.com/steinkel "steinkel (25 commits)")[![LordSimal](https://avatars.githubusercontent.com/u/9105243?v=4)](https://github.com/LordSimal "LordSimal (8 commits)")[![georgeconstantinou](https://avatars.githubusercontent.com/u/1926811?v=4)](https://github.com/georgeconstantinou "georgeconstantinou (4 commits)")[![zonuexe](https://avatars.githubusercontent.com/u/822086?v=4)](https://github.com/zonuexe "zonuexe (2 commits)")[![arusinowski](https://avatars.githubusercontent.com/u/1587389?v=4)](https://github.com/arusinowski "arusinowski (1 commits)")

###  Code Quality

TestsPHPUnit

Type Coverage Yes

### Embed Badge

![Health badge](/badges/cakedc-cakephp-phpstan/health.svg)

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

###  Alternatives

[deptrac/deptrac

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

3.0k8.8M118](/packages/deptrac-deptrac)[dereuromark/cakephp-tools

A CakePHP plugin containing lots of useful and reusable tools

3361.0M51](/packages/dereuromark-cakephp-tools)[ticketswap/phpstan-error-formatter

A minimalistic error formatter for PHPStan

87718.9k56](/packages/ticketswap-phpstan-error-formatter)[dereuromark/cakephp-dto

A CakePHP plugin for generating immutable Data Transfer Objects with full type safety

3099.1k6](/packages/dereuromark-cakephp-dto)[ec-europa/toolkit

Toolkit packaged for Drupal projects based on Robo.

40252.8k34](/packages/ec-europa-toolkit)[ergebnis/rector-rules

Provides rules for rector/rector.

10245.6k51](/packages/ergebnis-rector-rules)

PHPackages © 2026

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