1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00
psalm/docs/running_psalm/issues/ParamNameMismatch.md
Lexidor Digital 5d95cceb21
[easy fix] Update example for @no-named-arguments (#4170)
The text mentions `@no-named-arguments`, but the example shows `@no-named-params`.
`@no-named-params` can not be found in the psalm source.
Updated example to `@no-named-arguments`.
[https://github.com/vimeo/psalm/search?q=no-named-params&unscoped_q=no-named-params](search for no-named-params) 1 result (this example)
[https://github.com/vimeo/psalm/search?q=no-named-arguments&unscoped_q=no-named-arguments](search for no-named-arguments) 2 results (this example and in CommentAnalyzer.php)
2021-01-29 11:38:57 +01:00

2.3 KiB

ParamNameMismatch

Emitted when method overrides a parent method but renames a param.

<?php

class A {
    public function foo(string $str, bool $b = false) : void {}
}

class AChild extends A {
    public function foo(string $string, bool $b = false) : void {}
}

Why is this bad?

PHP 8 introduces named parameters which allow developers to call methods with explicitly-named parameters;

<?php

function callFoo(A $a) {
    $a->foo(str: "hello");
}

In the first example passing new AChild() to callFoo() results in a fatal error, as AChild's definition of the method foo() doesn't have a parameter named $str.

How to fix

You can change the child method param name to match:

<?php

class A {
    public function foo(string $str, bool $b = false) : void {}
}

class AChild extends A {
    public function foo(string $str, bool $b = false) : void {}
}

This fix can be applied automatically by Psalter.

Workarounds

@no-named-arguments

Alternatively you can ignore this issue by adding a @no-named-arguments annotation to the parent method:

<?php

class A {
    /** @no-named-arguments */
    public function foo(string $str, bool $b = false) : void {}
}

class AChild extends A {
    public function foo(string $string, bool $b = false) : void {}
}

Any method with this annotation will be prevented (by Psalm) from being called with named parameters, so the original issue does not matter.

Config allowNamedArgumentCalls="false"

This prevents any use of named params in your codebase. Ideal for self-contained projects, but less ideal for libraries.

It means the original code above will not emit any errors as long as the class A is defined in a directory that Psalm can scan.

Config allowInternalNamedArgumentCalls="false"

For library authors Psalm supports a more nuanced flag that tells Psalm to prohibit any named parameter calls on @internal classes or methods.

With that config value, this is now allowed:

<?php

/**
 * @internal
 */
class A {
    public function foo(string $str, bool $b = false) : void {}
}

class AChild extends A {
    public function foo(string $string, bool $b = false) : void {}
}