Skip to content

Null coalescing operator on multi-level array access #4592

@derrabus

Description

@derrabus

Bug report

If I apply the coalescing operator to a two-level array access ($foo[$one][$two]) where the second level is guaranteed to be set, phpstan does not take into account that the first level might be undefined.

If you run phpstan on the snippet below, it will complain that $name can never be null in sayHello1(). In sayHello2() however, the two levels are inverted. Here, the behavior is correct.

Code snippet that reproduces the problem

class HelloWorld
{
	/**
	 * @var array<string, array{name: string, email: string}>
	 */
	private array $contacts1 = [];
	
	/**
	 * @var array{names: array<string, string>, emails: array<string, string>}
	 */
	private array $contacts2 = ['names' => [], 'emails' => []];
	
	public function sayHello1(string $id): void
	{
		$name = $this->contacts1[$id]['name'] ?? null;
		if ($name === null) {
			throw new \InvalidArgumentException('Unknown contact.');
		}
		
		echo "Hello $name!";
	}

	public function sayHello2(string $id): void
	{
		$name = $this->contacts2['names'][$id] ?? null;
		if ($name === null) {
			throw new \InvalidArgumentException('Unknown contact.');
		}
		
		echo "Hello $name!";
	}
}

https://phpstan.org/r/766659f0-7300-4297-81ff-f32314bbb9ac

Expected output

The code should not produce any errors.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions