1

I have a function that checks if a value is null and after I call that function I use the value that is obviously not null.

but phpstan still says it could be null.

Do you guys have any solution for phpstan to know the outcome of this function.

protected ?string $filterCacheKey = null;
protected function usesFilterCaching(): bool
{
    return $this->filterCacheKey !== null;
}

Parameter #1 $key of method Illuminate\Contracts\Session\Session::get() expects string, string|null given.

if ($this->usesFilterCaching() && $this->request()->method() === Request::METHOD_GET) {
    $sessionCacheFilters = $this->filterStore()->get($this->filterCacheKey);

    return Arr::get($sessionCacheFilters, $filterName, $defaultChecked);
}
  • What is the signature of `$this->filterCacheKey`? As although you check it during the code run, a static analysis uses the signature which may show it can be null. – Nigel Ren Jan 09 '23 at 10:18
  • I think the problem might be that you are checking if a key is set, and then fetch data with it that does not exist. I think you should check if key exists and store has value at that key index, only then resume – Techno Jan 09 '23 at 11:10

3 Answers3

1

I think your problem is right here:

$sessionCacheFilters = $this->filterStore()->get($this->filterCacheKey); 

$this->filterStore() does not have a value at key $this->filterCacheKey

So I think your check should be:

if ($this->usesFilterCaching() && $this->filterStore()->get($this->filterCacheKey) != null && $this->request()->method() === Request::METHOD_GET)

Techno
  • 1,668
  • 1
  • 9
  • 19
0

Although your code is clearly checking the null value before it is used, phpstan does not check called methods. It is a static analysis tool that will only stick to parameter types and return types, not what checks occur inside a called function.

As a quick workaround for this problem, I would suggest removing the usesFilterCaching function altogether as it can be replaced with a simple if check like so:

if ($this->filterCacheKey && $this->request()->method() === Request::METHOD_GET) {
    $sessionCacheFilters = $this->filterStore()->get($this->filterCacheKey);

    return Arr::get($sessionCacheFilters, $filterName, $defaultChecked);
}

This will perform the same null check and the code will not be executed if the variable is null.

max
  • 134
  • 1
  • 3
0

I think this is the cleanest solution:

I added the following docblock to the usesFilterCaching() function.

/**
 * @phpstan-assert-if-true string $this->filterCacheKey
 */
protected function usesFilterCaching(): bool
{
    return $this->filterCacheKey !== null;
}

This sets $this->filterCacheKey to a string if the function returns true.