Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Psalm Laravel Package

vimeo/psalm

Psalm is a powerful PHP static analysis tool that finds type errors and bugs before runtime. Install via Composer, configure for your codebase, and run it locally or try the live demo at psalm.dev. Docs and integrations available for teams and CI.

View on GitHub
Deep Wiki
Context7

ClassMustBeFinal

Emitted when a non-final, non-abstract class with no child classes is found.

<?php

class A {}

Why this is bad

Non-final classes are bad for multiple reasons:

  • They allow overriding non-final methods and properties, which can lead to unexpected behavior and bugs if implementation details are changed during inheritance of classes not explicitly part of the public API (marked using the [@api](https://github.com/api) attribute).
  • A corollary of the above is that non-final classes increase the amount of code that must be covered by any backwards-compatibility promise.
    • In final classes, only public functions/properties/constants must be covered by the backwards compatibility promise.
    • In non-final classes, all private, protected and public functions/properties/constants must be covered by the backwards compatibility promise (private methods too, because changes to their code may not be compatible with overridden protected/public methods).
  • They are not optimized by Opcache and PHP itself, and thus are more expensive to use at runtime.
  • Psalm type inference is more complex and not as exact for non-final classes.

In general, the number of non-final classes in the codebase should be reduced as much as possible, both to speed up code execution and avoid unexpected bugs.

How to fix

Recommended, make the class final:

<?php

final class A {}

The above can also be automated using vendor/bin/psalm --alter --issues=ClassMustBeFinal.

If inheritance should still be allowed, reduce the surface covered by the backwards compatibility promise by making the class abstract (containing only the logic that should be overridable), and move any non-overridable logic to a new A class:

<?php

abstract class A {}

final class NewA extends A {}

Note: if non-final classes are needed for mocking in unit tests, simply use dg/bypass-finals in your unit tests to allow mocking final classes.

An alternative, not recommended for the above reasons, is to make the class part of the public API of your library with [@api](https://github.com/api).

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport