Parameter Closure Type #
Sometimes, you might want to change the type of a closure parameter to a function or method call based on the context. For example, the closure might have a generic argument, and you want to change the inner type.
You can create an extension that implements MethodParameterClosureTypeExtension:
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParameterReflection;
interface MethodParameterClosureTypeExtension
{
public function isMethodSupported(
MethodReflection $methodReflection,
ParameterReflection $parameter,
): bool;
public function getTypeTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
ParameterReflection $parameter,
Scope $scope,
): ?Type;
}
The implementation needs to be registered in your configuration file:
services:
-
class: MyApp\PHPStan\SomeParameterClosureTypeExtension
tags:
- phpstan.methodParameterClosureTypeExtension
There’s also analogous functionality for:
- static methods using
StaticMethodParameterClosureTypeExtensioninterface andphpstan.staticMethodParameterClosureTypeExtensionservice tag. - functions using
FunctionParameterClosureTypeExtensioninterface andphpstan.functionParameterClosureTypeExtensionservice tag.
Parameter Closure This #
While PHPStan supports @param-closure-this to change the meaning of $this inside closures, sometimes static PHPDocs are not sufficient or don’t have the necessary context to describe the closure’s $this parameter.
You can create an extension that implements MethodParameterClosureThisExtension:
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParameterReflection;
interface MethodParameterClosureThisExtension
{
public function isMethodSupported(
MethodReflection $methodReflection,
ParameterReflection $parameter,
): bool;
public function getClosureThisTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
ParameterReflection $parameter,
Scope $scope,
): ?Type;
}
The implementation needs to be registered in your configuration file:
services:
-
class: MyApp\PHPStan\SomeParameterClosureThisExtension
tags:
- phpstan.methodParameterClosureThisExtension
There’s also analogous functionality for:
- static methods using
StaticMethodParameterClosureThisExtensioninterface andphpstan.staticMethodParameterClosureThisExtensionservice tag. - functions using
FunctionParameterClosureThisExtensioninterface andphpstan.functionParameterClosureThisExtensionservice tag.
Tracking dependencies for the result cache #
If the extension reads something PHPStan doesn’t know about to resolve the type, like a configuration file, typehint the $scope parameter as Scope&DependencyTracker in the PHPDoc and track it with $scope->trackFileDependency() or one of the other DependencyTracker methods. When it changes, the result cache analyses the file with the call again. This applies to both parameter closure type and parameter closure this extensions. Learn more »