Emitted when an attempt is made to instantiate an abstract class:
abstract class A {}
new A();
Emitted when calling a function with an argument which has a less specific type than the function expects
class A {}
class B extends A {}
function takesA(A $a) : void {
takesB($a);
}
function takesB(B $b) : void {}
Emitted when assigning from a function that returns void
:
function foo() : void {}
$a = foo();
Emitted when a class references itself as one of its parents
class A extends B {}
class B extends A {}
Emitted when a by-ref variable is set in two different branches of an if to different types.
class A {
/** @var int */
private $foo;
public function __construct(int &$foo) {
$this->foo = &$foo;
}
}
class B {
/** @var string */
private $bar;
public function __construct(string &$bar) {
$this->bar = &$bar;
}
}
if (rand(0, 1)) {
$v = 5;
$c = (new A($v)); // $v is constrained to an int
} else {
$v = "hello";
$c = (new B($v)); // $v is constrained to a string
}
$v = 8;
Emitted when encountering a continue
statement outside a loop context.
$a = 5;
continue;
Emitted when referring to a deprecated class:
/** @deprecated */
class A {}
new A();
Emitted when referring to a deprecated constant:
class A {
/** @deprecated */
const FOO = 'foo';
}
echo A::FOO;
Emitted when referring to a deprecated interface
/** @deprecated */
interface I {}
class A implements I {}
Emitted when calling a deprecated method on a given class:
class A {
/** @deprecated */
public function foo() : void {}
}
(new A())->foo();
Emitted when getting/setting a deprecated property of a given class
class A {
/**
* @deprecated
* @var ?string
*/
public $foo;
}
(new A())->foo = 5;
Emitted when referring to a deprecated trait:
/** @deprecated */
trait T {}
class A {
use T;
}
Emitted when conditional doesn't make sense given the docblock types supplied.
/**
* @param string $s
*
* @return void
*/
function foo($s) {
if ($s === 5) { }
}
Emitted when an array has a key more than once
$arr = [
'a' => 1,
'b' => 2,
'c' => 3,
'c' => 4,
];
Emitted when a class is defined twice
class A {}
class A {}
Emitted when a function is defined twice
function foo() : void {}
function bar() : void {}
function foo() : void {}
Emitted when a method is defined twice
class A {
public function foo() {}
public function foo() {}
}
Emitted when a function has a param defined twice
function foo(int $b, string $b) {}
Emitted when attempting to access a value on an empty array
$a = [];
$b = $a[0];
Emitted if a return statement contains a false value, but the function return type does not allow false
function foo() : string {
if (rand(0, 1)) {
return "foo";
}
return false; // emitted here
}
Emitted when using false
as part of an operation (e.g. +
, .
, ^
etc.)
echo false . 'hello';
Emitted when Psalm encounters a var_dump, exec or similar expression that may make your code more vulnerable
var_dump("bah");
Emitted when Psalm encounters an echo statement and the forbidEcho
flag in your config is set to true
echo("bah");
Emitted when a class that inherits another, or implements an interface, has docblock return type that's entirely different to the parent. Subclasses of the parent return type are permitted, in docblocks.
class A {
/** @return bool */
public function foo() {
return true;
}
}
class B extends A {
/** @return string */
public function foo() {
return "hello";
}
}
Emitted when implicitly converting an object with a __toString
method to a string
class A {
public function __toString() {
return "foo";
}
}
function takesString(string $s) : void {}
takesString(new A);
Emitted when a public/private class constant is not accessible from the calling context
class A {
protected const FOO = 'FOO';
}
echo A::FOO;
Emitted when attempting to access a protected/private method from outside its available scope
class A {
protected function foo() : void {}
}
echo (new A)->foo();
Emitted when an attempt is made to instantiate an interface:
interface I {}
new I();
Emitted when attempting to access a protected/private property from outside its available scope
class A {
/** @return string */
protected $foo;
}
echo (new A)->foo;
Emitted when attempting to access a class marked as internal an unrelated namespace or class.
namespace A {
/**
* @internal
*/
class Foo { }
}
namespace B {
class Bat {
public function batBat() {
$a = new \A\Foo();
}
}
}
Emitted when attempting to access a method marked as internal an unrelated namespace or class.
namespace A {
class Foo {
/**
* @internal
*/
public static function barBar(): void {
}
}
}
namespace B {
class Bat {
public function batBat() {
\A\Foo::barBar();
}
}
}
Emitted when attempting to access a property marked as internal from an unrelated namespace or class.
namespace A {
class Foo {
/**
* @internal
* @var ?int
*/
public $foo;
}
}
namespace B {
class Bat {
public function batBat() : void {
echo (new \A\Foo)->foo;
}
}
}
Emitted when a supplied function/method argument is incompatible with the method signature or docblock one.
class A {}
function foo(A $a) : void {}
foo("hello");
Emitted when attempting to access an array offset on a value that does not permit it
$arr = 5;
echo $arr[0];
Emitted when attempting to assign a value on a non-array
$arr = 5;
$arr[0] = 3;
Emitted when attempting to access an array using a value that's not a valid offset for that array
$a = [5, 20, 18];
echo $a["hello"];
Emitted when attempting to cast a value that's not castable
class A {}
$a = new A();
$b = (string)$a;
Emitted when trying to catch a class/interface that doesn't extend Exception
or implement Throwable
class A {}
try {
$worked = true;
}
catch (A $e) {}
Emitted when referencing a class with the wrong casing
class Foo {}
(new foo());
Emitted when you have allowStringToStandInForClass="false"
in your config and you’re passing a string instead of calling a class directly
class Foo {}
$a = "Foo";
new $a();
Emitted when trying to clone a value that's not cloneable
$a = "hello";
$b = clone $a;
Emitted when there's an error in a docblock type
/** @var array() */
$a = [];
Emitted when a docblock param name doesn’t match up with a named param in the function.
/**
* @param string[] $bar
*/
function foo(array $barb): void {
//
}
Emitted when a function can return a nullable value, but its given return type says otherwise
function foo() : string {
if (rand(0, 1)) {
return "foo";
}
return false;
}
Emitted when calling a function on a non-callable variable
$a = 5;
$b = $a();
Emitted when there's a reference to the global keyword where it's not expected
global $e;
Emitted when trying to iterate over a value that's not iterable
$a = 5;
foreach ($a as $b) {}
Emitted when attempting to call a method on a non-object
$a = 5;
$a->foo();
Emitted when a function can return a nullable value, but its given return type says otherwise
function foo() : string {
if (rand(0, 1)) {
return "foo";
}
return null;
}
Emitted when using something as an operand that is unexpected
class A {}
echo (new A) . ' ';
Emitted when a function parameter default clashes with the type Psalm expects the param to be
function foo(int $i = false) : void {}
Emitted when passing a non-variable to a function that expects a by-ref variable
function foo(array &$arr) : void {}
foo([0, 1, 2]);
Emitted when attempting to assign a property to a non-object
$a = "foo";
$a->bar = "bar";
Emitted when attempting to assign a value to a property that cannot contain that type.
class A {
/** @var string|null */
public $foo;
}
$a = new A();
$a->foo = new stdClass();
Emitted when attempting to get a property from a non-object
$a = "foo";
echo $a->bar;
Emitted when a function return statement is incorrect
function foo() : string {
return 5; // emitted here
}
Emitted when a function’s signature return type is incorrect (often emitted with `InvalidReturnStatement`)
function foo() : int {
if (rand(0, 1)) {
return "hello";
}
return 5;
}
Emitted when a scalar value is passed to a method that expected another scalar type
function foo(int $i) : void {}
function bar(string $s) : void {
if (is_numeric($s)) {
foo($s);
}
}
Emitted when referring to $this
outside a class
echo $this;
Emitted when trying to call an instance function statically
class A {
/** @var ?string */
public $foo;
public function bar() : void {
echo $this->foo;
}
}
A::bar();
Emitted when using the @extends
/@implements
annotation to extend a class that has a template type constraint, where that extended value does not satisfy the parent class/interface's constraints.
/**
* @template T as object
*/
class Base {}
/** @template-extends Base<int> */
class SpecializedByInheritance extends Base {}
Emitted when trying to throw a class that doesn't extend Exception
or implement Throwable
class A {}
throw new A();
Emitted when a __toString
method does not always return a string
class A {
public function __toString() {
return true;
}
}
Emitted when a class implements an interface method but its return type is less specific than the interface method return type
class A {}
class B extends A {}
interface I {
/** @return B[] */
public function foo();
}
class D implements I {
/** @return A[] */
public function foo() {
return [new A, new A];
}
}
Emitted when a return statement is more general than the return type given for the function
class A {}
class B extends A {}
function foo() : B {
return new A(); // emitted here
}
Emitted when a return type covers more possibilities than the function itself
function foo() : ?int {
return 5;
}
Emitted when logic inside a loop invalidates one of the conditionals of the loop
for ($i = 0; $i < 10; $i++) {
$i = 5;
}
Emitted when a method parameter differs from a parent method parameter, or if there are fewer parameters than the parent method
class A {
public function foo(int $i) : void {}
}
class B extends A {
public function foo(string $s) : void {}
}
Emitted when a __clone
, __construct
, or __destruct
method is defined with a return type.
class A {
public function __clone() : void {}
}
Emitted when an @param
entry in a function’s docblock doesn’t match the param typehint,
class A {}
class B {}
/**
* @param B $b // emitted here
*/
function foo(A $b) : void {}
This, however, is fine:
class A {}
class B extends A {}
/**
* @param B
*/
function foo(A $b) : void {}
Emitted when an @return
entry in a function’s docblock doesn’t match the function return typehint
class A {}
class B {}
/**
* @return B // emitted here
*/
function foo() : A {
return new A();
}
This, however, is fine:
class A {}
class B extends A {}
/**
* @return B // emitted here
*/
function foo() : A {
return new B();
}
Emitted when an @param
entry in a function’s docblock doesn’t match the param typehint
/**
* @param int $b
*/
function foo(string $b) : void {}
Emitted when a required param is before a param that is not required. Included in Psalm because it is an E_WARNING in PHP
function foo(int $i = 5, string $j) : void {}
Emitted when a closure parameter has no type information associated with it
$a = function($a): string {
return "foo";
};
Emitted when a closure lacks a return type
$a = function() {
return "foo";
};
Emitted when non-null properties without default values are defined in a class without a __construct
method
class A {
/** @var string */
public $foo;
}
Emitted when referencing a class that doesn’t exist
/**
* @psalm-suppress UndefinedClass
*/
class A extends B {}
$a = new A();
Emitted when a docblock is present, but the type is missing or badly formatted
/** @var $a */
$a = [];
Emitted when using include
or require
on a file that does not exist
require("nonexistent.php");
Emitted when a function parameter has no type information associated with it
function foo($a) : void {}
Emitted when a property is defined on a class without a type
class A {
public $foo;
}
Emitted when a function doesn't have a return type defined
function foo() {
return "foo";
}
Emitted when using the @extends
/@implements
annotation to extend a class without
extending all its template params.
/**
* @template-implements IteratorAggregate<int>
*/
class SomeIterator implements IteratorAggregate
{
public function getIterator() {
yield 5;
}
}
Emitted when a function doesn't have a return type defined
function foo(int $x, int $y) : int {
if ($y === 0) {
throw new \InvalidArgumentException('Cannot divide by zero');
}
return intdiv($x, $y);
}
Emitted when Psalm cannot determine the type of an argument
function takesInt(int $i) : void {}
takesInt($_GET['foo']);
Emitted when Psalm cannot be sure that part of an array/iterabble argument's type constraints can be fulfilled
function foo(array $a) : void {
takesStringArray($a);
}
/** @param string[] $a */
function takesStringArray(array $a) : void {}
Emitted when trying to access an array offset on a value whose type Psalm cannot determine
echo $_GET['foo'][0];
Emitted when trying to assign a value to an array offset on a value whose type Psalm cannot determine
$_GET['foo'][0] = "5";
Emitted when attempting to access an array offset where Psalm cannot determine the offset type
echo [1, 2, 3][$_GET['foo']];
Emitted when trying to access an array with a less specific offset than is expected
/**
* @param array<array-key, int> $a
* @param array<int, string> $b
*/
function foo(array $a, array $b) : void {
foreach ($a as $j => $k) {
echo $b[$j];
}
}
Emitted when assigning a variable to a value for which Psalm cannot infer a type
$a = $_GET['foo'];
Emitted when calling a function on a value whose type Psalm cannot infer.
/** @psalm-suppress MixedAssignment */
$a = $_GET['foo'];
$a();
Emitted when Psalm cannot determine a function's return type
function foo() : int {
return $_GET['foo'];
}
Emitted when calling a method on a value that Psalm cannot infer a type for
/** @param mixed $a */
function foo($a) : void {
$a->foo();
}
Emitted when Psalm cannot infer a type for an operand in any calculated expression
echo $_GET['foo'] + "hello";
Emitted when assigning a property to a value for which Psalm cannot infer a type
/** @param mixed $a */
function foo($a) : void {
$a->foo = "bar";
}
Emitted when retrieving a property on a value for which Psalm cannot infer a type
/** @param mixed $a */
function foo($a) : void {
echo $a->foo;
}
Emitted when Psalm cannot be sure that part of an array/iterabble argument's type constraints can be fulfilled
class A {
/** @var string[] */
public $takesStringArray = [];
}
function foo(A $a, array $arr) : void {
$a->takesStringArray = $arr;
}
Emitted when Psalm cannot determine the type of a given return statement
function foo() : int {
return $_GET['foo']; // emitted here
}
Emitted when Psalm cannot be sure that part of an array/iterabble return type's constraints can be fulfilled
/**
* @return string[]
*/
function foo(array $a) : array {
return $a;
}
Emitted when assigning a value on a string using a value for which Psalm cannot infer a type
"hello"[0] = $_GET['foo'];
Emitted when a class implements an interface method but a param type is less specific than the interface method param type
class A {}
class B extends A {
public function bar(): void {}
}
class C extends A {
public function bar(): void {}
}
class D {
public function foo(A $a): void {}
}
class E extends D {
/** @param B|C $a */
public function foo(A $a): void {
$a->bar();
}
}
Emitted when the declared return type for a method is more specific than the inferred one (emitted in the same methods that LessSpecificReturnStatement
is)
class A {}
class B extends A {}
function foo() : B {
/** @psalm-suppress LessSpecificReturnStatement */
return new A();
}
Emitted when using the result of a function that never returns.
/**
* @return never-returns
*/
function foo() : void {
exit();
}
$a = foo();
Emitted when trying to fetch a property on an interface as interfaces, by definition, do not have definitions for properties.
interface I {}
class A implements I {
/** @var ?string */
public $foo;
}
function bar(I $i) : void {
if ($i->foo) {}
}
Emitted when calling a non-static function statically
class A {
public function foo(): void {}
public static function bar(): void {
self::foo();
}
}
Emitted if a return statement contains a null value, but the function return type is not nullable
function foo() : string {
if (rand(0, 1)) {
return "foo";
}
return null; // emitted here
}
Emitted when calling a function with a null value argument when the function does not expect it
function foo(string $s) : void {}
foo(null);
Emitted when trying to access an array value on null
$arr = null;
echo $arr[0];
Emitted when trying to access an array offset with null
$arr = ['' => 5, 'foo' => 1];
echo $arr[null];
Emitted when trying to use null
as a callable
$arr = null;
echo $arr();
Emitted when iterating over null
foreach (null as $a) {}
Emitted when using null
as part of an operation (e.g. +
, .
, ^
etc.)
echo null . 'hello';
Emitted when trying to set a property on null
$a = null;
$a->foo = "bar";
Emitted when trying to fetch a property on a null
value
$a = null;
echo $a->foo;
Emitted when attempting to call a method on null
$a = null;
$a->foo();
Emitted when a method is less accessible than its parent
class A {
public function foo() : void {}
}
class B extends A {
protected function foo() : void {}
}
Emitted when a property is less accessible than the same-named property in its parent class
class A {
/** @var string|null */
public $foo;
}
class B extends A {
/** @var string|null */
protected $foo;
}
Emitted when a paradox is encountered in your programs logic that could not be caught by RedundantCondition
function foo($a) : void {
if ($a) return;
if ($a) echo "cannot happen";
}
Emitted when using parent::
in a class without a parent class.
class A {
public function foo() : void {
parent::foo();
}
}
Emitted when the PHP Parser encounters an error.
class A {
public function foo() : void {
echo "foo"
}
}
Can be emitted by plugins.
Emitted when a function argument is possibly false
, but the function doesn’t expect false
. This is distinct from a function argument is possibly bool
, which results in PossiblyInvalidArgument
.
function foo(string $s) : void {
$a_pos = strpos($s, "a");
echo substr($s, $a_pos);
}
Emitted when trying to iterate over a value that may be false
$arr = rand(0, 1) ? [1, 2, 3] : false;
foreach ($arr as $a) {}
Emitted when using a possibly false
value as part of an operation (e.g. +
, .
, ^
etc).
function foo(string $a) : void {
echo strpos($a, ":") + 5;
}
Emitted when trying to assign a value that may be false to a property that only takes non-false values.
class A {
/** @var int */
public $foo = 0;
}
function assignToA(string $s) {
$a = new A();
$a->foo = strpos("haystack", $s);
}
Emitted when making a method call on a value than might be false
class A {
public function bar() : void {}
}
/** @return A|false */
function foo() {
return rand(0, 1) ? new A : false;
}
foo()->bar();
Emitted when
/** @return int|stdClass */
function foo() {
return rand(0, 1) ? 5 : new stdClass;
}
function bar(int $i) : void {}
bar(foo());
Emitted when attempting to access an array offset on a value that may not be an array
$arr = rand(0, 1) ? 5 : [4, 3, 2, 1];
echo $arr[0];
Emitted when attempting to assign an array offset on a value that may not be an array
$arr = rand(0, 1) ? 5 : [4, 3, 2, 1];
$arr[0] = "hello";
Emitted when attempting to cast a value that may not be castable
class A {}
class B {
public function __toString() {
return 'hello';
}
}
$c = (string) (rand(0, 1) ? new A() : new B());
Emitted when it’s possible that the array offset is not applicable to the value you’re trying to access.
$arr = rand(0, 1) ? ["a" => 5] : "hello";
echo $arr[0];
Emitted when trying to call a function on a value that may not be callable
$a = rand(0, 1) ? 5 : function() : int { return 5; };
$b = $a();
Emitted when trying to iterate over a value that may be invalid
$arr = rand(0, 1) ? [1, 2, 3] : "hello";
foreach ($arr as $a) {}
Emitted when trying to call a method on a value that may not be an object
class A {
public function bar() : void {}
}
/** @return A|int */
function foo() {
return rand(0, 1) ? new A : 5;
}
foo()->bar();
Emitted when using a possibly invalid value as part of an operation (e.g. +
, .
, ^
etc.
function foo() : void {
$b = rand(0, 1) ? [] : 4;
echo $b + 5;
}
Emitted when trying to assign a property on a value that may not be an object or may be an object that doesn’t have the desired property.
class A {
/** @var ?string */
public $bar;
}
/** @return A|int */
function foo() {
return rand(0, 1) ? new A : 5;
}
$a = foo();
$a->bar = "5";
Emitted when trying to assign a possibly invalid value to a typed property.
class A {
/** @var int[] */
public $bb = [];
}
class B {
/** @var string[] */
public $bb;
}
$c = rand(0, 1) ? new A : new B;
$c->bb = ["hello", "world"];
Emitted when trying to fetch a property on a value that may not be an object or may be an object that doesn’t have the desired property.
class A {
/** @var ?string */
public $bar;
}
/** @return A|int */
function foo() {
return rand(0, 1) ? new A : 5;
}
$a = foo();
echo $a->bar;
Emitted when calling a function with a value that’s possibly null when the function does not expect it
function foo(string $s) : void {}
foo(rand(0, 1) ? "hello" : null);
Emitted when trying to access an array offset on a possibly null value
function foo(?array $a) : void {
echo $a[0];
}
Emitted when trying to set a value on a possibly null array
$a = null;
$a[0][] = 1;
Emitted when trying to access a value on an array using a possibly null offset
function foo(?int $a) : void {
echo [1, 2, 3, 4][$a];
}
Emitted when trying to call a function on a value that may be null
function foo(?callable $a) : void {
$a();
}
Emitted when trying to iterate over a value that may be null
function foo(?array $arr) : void {
foreach ($arr as $a) {}
}
Emitted when using a possibly null
value as part of an operation (e.g. +
, .
, ^
etc.)
function foo(?int $a) : void {
echo $a + 5;
}
Emitted when trying to assign a property to a possibly null object
class A {
/** @var ?string */
public $foo;
}
function foo(?A $a) : void {
$a->foo = "bar";
}
Emitted when trying to assign a value that may be null to a property that only takes non-null values.
class A {
/** @var string */
public $foo = "bar";
}
function assignToA(?string $s) {
$a = new A();
$a->foo = $s;
}
Emitted when trying to fetch a property on a possibly null object
class A {
/** @var ?string */
public $foo;
}
function foo(?A $a) : void {
echo $a->foo;
}
Emitted when trying to call a method on a possibly null value
class A {
public function bar() : void {}
}
function foo(?A $a) : void {
$a->bar();
}
Emitted when trying to access a possibly undefined array offset
if (rand(0, 1)) {
$arr = ["a" => 1, "b" => 2];
} else {
$arr = ["a" => 3];
}
echo $arr["b"];
Emitted when trying to access a variable in the global scope that may not be defined
if (rand(0, 1)) {
$a = 5;
}
echo $a;
Emitted when trying to access a method that may not be defined on the object
class A {
public function bar() : void {}
}
class B {}
$a = rand(0, 1) ? new A : new B;
$a->bar();
Emitted when trying to access a variable in function scope that may not be defined
function foo() : void {
if (rand(0, 1)) {
$a = 5;
}
echo $a;
}
Emitted when --find-dead-code
is turned on and Psalm cannot find any calls to a given class method
class A {
public function foo() : void {}
public function bar() : void {}
}
(new A)->foo();
Emitted when --find-dead-code
is turned on and Psalm cannot find any uses of a particular parameter in a public/protected method
class A {
public function foo(int $a, int $b) : int {
return $a + 4;
}
}
$a = new A();
$a->foo(1, 2);
Emitted when --find-dead-code
is turned on and Psalm cannot find any uses of a particular public/protected property
class A {
/** @var string|null */
public $foo;
/** @var int|null */
public $bar;
}
$a = new A();
echo $a->foo;
Emitted when a non-null property without a default value is declared but not set in the class’s constructor
class A {
/** @var string */
public $foo;
public function __construct() {}
}
Emitted when setting a property with an value which has a less specific type than the property expects
class A {}
class B extends A {}
function takesA(C $c, A $a) : void {
$c->b = $a;
}
class C {
/** @var ?B */
public $b;
}
Emitted when iterating over an object’s properties. This issue exists because it may be undesired behaviour (e.g. you may have meant to iterate over an array)
class A {
/** @var string|null */
public $foo;
/** @var string|null */
public $bar;
}
function takesA(A $a) {
foreach ($a as $property) {}
}
Emitted when conditional is redundant given previous assertions
class A {}
function foo(A $a) : ?A {
if ($a) return $a;
return null;
}
Emitted when conditional is redundant given information supplied in one or more docblocks.
This may be desired (e.g. when checking user input) so is distinct from RedundantCondition, which only applies to non-docblock types.
/**
* @param string $s
*
* @return void
*/
function foo($s) {
if (is_string($s)) {};
}
Emitted when changing the type of a pass-by-reference variable
function foo(string &$a) {
$a = 5;
}
Emitted when using a reserved word as a class name
function foo(resource $res) : void {}
Emitted when a method's signature or return type differs from corresponding trait-defined method
trait T {
abstract public function foo(int $i);
}
class A {
use T;
public function foo(string $s) : void {}
}
Emitted when calling a function with fewer arguments than the function has parameters
function foo(string $a) : void {}
foo();
Emitted when calling a function with more arguments than the function has parameters
function foo(string $a) : void {}
foo("hello", 4);
Emitted when using the @extends
/@implements
annotation to extend a class and adds too
many types.
/**
* @template-implements IteratorAggregate<int, string, int>
*/
class SomeIterator implements IteratorAggregate
{
public function getIterator() {
yield 5;
}
}
Emitted when checking a non-nullable type for null
$a = "hello";
if ($a === null) {}
Emitted checking whether one value has a type or value that is impossible given its currently-known type
$a = "hello";
if ($a === 5) {}
Emitted when a possible exception isn't caught in global scope
/**
* @throws \Exception
*/
function foo() : int {
return random_int(0, 1);
}
foo();
Emitted when referencing a class that doesn’t exist
$a = new A();
Emitted when referencing a constant that doesn’t exist
echo FOO_BAR;
Emitted when referencing a function that doesn't exist
foo();
Emitted when referencing a variable that doesn't exist
echo $a;
Emitted when referencing an interface that doesn’t exist but does have an identically-named class.
class C {}
interface I extends C {}
Emitted when calling a method that doesn’t exist
class A {}
A::foo();
Emitted when calling a method that doesn’t exist on an interface
interface I {}
function foo(I $i) {
$i->bar();
}
Emitted when assigning a property on an object that doesn’t have that property defined
class A {}
$a = new A();
$a->foo = "bar";
Emitted when getting a property on an object that doesn’t have that property defined
class A {}
$a = new A();
echo $a->foo;
Emitted when assigning a property on an object in one of that object’s methods when no such property exists
class A {
function foo() {
$this->foo = "bar";
}
}
Emitted when getting a property for an object in one of that object’s methods when no such property exists
class A {
function foo() {
echo $this->foo;
}
}
Emitted when referencing a trait that doesn’t exist
class A {
use T;
}
Emitted when referencing a variable that doesn't exist in a given function’s scope
function foo() {
echo $a;
}
Emitted when --find-dead-code
is turned on and Psalm encounters code that will not be evaluated
function foo() : void {
return;
$a = "foo";
}
Emitted when a class extends another, but does not implement all of its abstract methods
abstract class A {
abstract public function foo();
}
class B extends A {}
Emitted when a class implements
an interface but does not implement all of its methods
interface I {
public function foo();
}
class A implements I {}
Emitted when a property is used in a constructor before it is initialized
class A {
/** @var string */
public $foo;
public function __construct() {
echo strlen($this->foo);
$this->foo = "foo";
}
}
Emitted when Psalm encounters an expression that it doesn't know how to handle. This should never happen.
Emitted when Psalm encounters a code construct that it doesn't know how to handle. This should never happen.
Emitted when Psalm cannot figure out what specific file is being included/required by PHP.
function requireFile(string $s) : void {
require_once($s);
}
Emitted when --find-dead-code
is turned on and Psalm cannot find any uses of a given class
class A {}
class B {}
$a = new A();
Emitted when --find-dead-code
is turned on and Psalm cannot find any uses of a given private method or function
class A {
public function __construct() {
$this->foo();
}
private function foo() : void {}
private function bar() : void {}
}
$a = new A();
Emitted when --find-dead-code
is turned on and Psalm cannot find any uses of a particular parameter in a closure.
$a = function (int $a, int $b) : int {
return $a + 4;
};
/**
* @param callable(int,int):int $c
*/
function foo(callable $c) : int {
return $c(2, 4);
}
Emitted when --find-dead-code
is turned on and Psalm cannot find any uses of a particular parameter in a private method or function
function foo(int $a, int $b) : int {
return $a + 4;
}
Emitted when --find-dead-code
is turned on and Psalm cannot find any uses of a private property
class A {
/** @var string|null */
private $foo;
/** @var int|null */
private $bar;
public function getFoo(): ?string {
return $this->foo;
}
}
$a = new A();
echo $a->getFoo();
Emitted when --find-dead-code
is turned on and Psalm cannot find any references to a variable, once instantiated
function foo() : void {
$a = 5;
$b = 4;
echo $b;
}