phpstan/phpstan-nette

Nette 3.2 Unreachable statement after adding types to __get method in Nette\Database\Row

Closed this issue · 15 comments

Sahtii commented

Unreachable statement - code above always terminates.
PHPStan wrongly assumes that this code in Nette\Database\Row always throws Exception and assumes that the further code will not execute.
This was not a case in Nette 3.1, problem occured after updating to Nette 3.2

public function __get(mixed $key): never
 {
 $hint = Nette\Utils\Helpers::getSuggestion(array_map('strval', array_keys((array) $this)), $key);
 throw new Nette\MemberAccessException("Cannot read an undeclared column '$key'" . ($hint ? ", did you mean '$hint'?" : '.'));
 }

This happens for example for code

code
$row->variable 
code

Looks like it works as designed: the __get always throws an exception (and returns never), so:

code 1
$row->variable 
code 2

"code 2" in this example will not be executed.

What here I do not understand?

Anyway, feel free to create a small reproducing repository, so I can better understand the problem. Thanks.

Problem is that $row can have property variable (it is universal objevt crate) but PHPStan thinks it always terminates.

@MartinMystikJonas Exactly, $row->variable works without any issues and doesn't throw any errors (in our code), because the column variable is selected from the database.

I understand now. The class doesn't have __set so properties are assigned as "dynamic" properties. The __get is only executed for properties that do not exist.

I say this class needs to be removed from universalObjectCratesClasses (

- Nette\Database\IRow
) and needs its own PropertiesClassReflectionExtension.

And is this work for you or for someone else?

Anyone who wants it fixed ;) (I'll probably not get to it anytime soon.)

spaze commented

Hey @Sahtii, can you check if it still happens for you with PHPStan 1.12? I had the same issue but after updating to 1.12 the problem seems gone.

Sahtii commented

Hi @spaze , unfortunately it still happens for my code. What version of phpstan-nette do you use ? If there is some magic with interaction of versions of these two libraries.

spaze commented

Hey @Sahtii, it stopped when I'm updated to PHPStan 1.12.0 (latest is 1.12.2) and phpstan-nette extension 1.3.8 (the current latest). I also use the bleeding edge configuration. See this commit in my repo where I had to unignore the error spaze/michalspacek.cz@2ff7216

Update: also tested with the latest 1.12.2, with or without bleeding edge, still not getting this error.

Sahtii commented

@spaze I have tried it with both versions for PHPStan (1.12.0 and 1.12.2) and latest version of phpstan-nette extension 1.3.8 but unfortunately it still have not work for me. What is your Nette version ? Mine is 3.2.5

spaze commented

I'm using Nette "by packages", trying to keep up to date. My nette/database is 3.2.4, the latest stable release, see https://github.com/spaze/michalspacek.cz/blob/2866af7286a337726da7582ab08682bf5a16f20c/site/vendor/composer/installed.php#L141

Sahtii commented

Yes, update to 3.2.4 helped.

So for anyone searching for this:
You just need nette/database: 3.2.4

spaze commented

For completeness, seems that this change in nette/database 3.2.4 (or earlier 3.2.3 which was removed later and replaced with 3.2.4) nette/database#303 is what fixed this issue.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.