phpstan: phpstan should not trust the phpdoc

Summary of a problem or a feature request

Result of || is always false is wrongly reported for a parameter validation.

Code snippet that reproduces the problem

   /**
     * @param SerializerInterface&ArrayTransformerInterface $originalSerializer must implement both SerializerInterface and ArrayTransformerInterface interfaces
     */
    public function __construct(
        $originalSerializer,
    ) {
        if (!$originalSerializer instanceof SerializerInterface
            || !$originalSerializer instanceof ArrayTransformerInterface
        ) {
            throw new \InvalidArgumentException(sprintf(
                'Original serializer must implement both ArrayTransformerInterface and SerializerInterface, but is %s',
                \get_class($originalSerializer)
            ));
        }

Expected output

This code seems fine correct to me. The check is needed because there is no PHP parameter declaration.

For context, this happens in https://github.com/liip/serializer-jms-adapter/pull/1/ - our workaround was to ignore the warning about || always being false.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 17 (12 by maintainers)

Most upvoted comments

Hi, I have great news! I’ve spent some time over the weekend solving this issue. You now have the option to treat types coming from @param PHPDocs as uncertain so these (and similar) errors won’t be reported.

You can set treatPhpDocTypesAsCertain: false in your phpstan.neon once PHPStan 0.12.6 in the coming days.

When you encounter such an error when running PHPStan, you will also get this helpful hint about the config option:

Screenshot 2020-01-18 at 18 17 19

You can also try out the behaviour in the online playground: https://phpstan.org/r/b945483f-7c2a-4e09-ad04-1468ee63dab9

Using ignoreErrors is not a great solution here. The lowest level of granularity possible with ignoreErrors is per file, so other valid errors with same message would now be ignored too within the file.

In projects this is the correct behavior. When you refactor your code you want to catch dead if statements. And since PHPStan makes sure the method calls are valid those cases really should never happen. However, in libraries you want to do checks like this because you can’t trust the user to pass values of the correct type, just like you did.

Basically, if:

  • the project is a library
  • the method is public
  • the method is not @internal

the phpDoc types can’t be trusted.