phan / phan

Phan is a static analyzer for PHP. Phan prefers to avoid false-positives and attempts to prove incorrectness rather than correctness.
https://github.com/phan/phan/wiki
Other
5.53k stars 359 forks source link

false positive PhanUndeclaredFunctionInCallable with PDO::query for callable|string #2590

Open dumistoklus opened 5 years ago

dumistoklus commented 5 years ago

This sample throw PhanUndeclaredFunctionInCallable Call to undeclared function UserMe in callable

class UserMe {
    public $id;
}

$db = new \PDO('', '', '');
$stmt = $db->query('SELECT * FROM users');

$stmt->fetchAll(\PDO::FETCH_CLASS, UserMe::class);

It is a bug?

TysonAndre commented 5 years ago

That's a known issue. Phan checks any parameter type containing callable and warns if strings aren't callable. This is because this was implemented prior to the callable-string type (and phan doesn't support intersection types yet) - also, many libraries would predate callable-string or intersection types, and use callable|string where callable&string would be the intended definition (or callable|string|null instead of (callable&string)|null.

It could be worked around by adding a plugin to override the param analysis of fetchAll based on the first argument, but it'd be more reasonable to fix the root cause in Phan's type system first to avoid extra code for special cases. Suppressing this is recommended until then (e.g. phan-suppress-next-line)

src/Phan/Language/Internal/FunctionSignatureMap.php

'PDOStatement::fetchAll' => ['array|false', 'how='=>'int', 'fetch_argument='=>'int|string|callable', 'ctor_args='=>'?array'],

donatj commented 1 week ago

This has been a longstanding problem for us. Our Di container accepts a class-string|callable and every single call to that needs to be ignored.

I'm hopeful someday this might be resolved.