Menu

Restricted Usage Extensions

Available in PHPStan 2.1.13

These extensions allow you to restrict where methods, properties, functions etc. can be accessed from without implementing full-fledged custom rules. The implementation is all about applying the core concepts so check out that guide first and then continue here.

Methods #

To report method calls from restricted places, implement RestrictedMethodUsageExtension interface.

It accepts method reflection and Scope. It looks like this:

namespace PHPStan\Rules\RestrictedUsage;

use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ExtendedMethodReflection;

interface RestrictedMethodUsageExtension
{
	public function isRestrictedMethodUsage(
		ExtendedMethodReflection $methodReflection,
		Scope $scope,
	): ?RestrictedUsage;
}

This extension is called for traditional method calls like $foo->doBar(1, 2, 3), but also for first-class callables like $foo->doBar(...). It’s also called for static method calls like Foo::doBar(1, 2, 3) and the first-class callable counterpart Foo::doBar(...).

It can decide not to report anything, or to return RestrictedUsage object which carries the error message and identifier.

Here’s an example of an implementation:

if (!str_contains($methodReflection->getName(), 'thankYou')) {
	// we're already interested in method containing "thankYou"
	return null;
}

$inFunction = $scope->getFunction();
if ($inFunction !== null && str_contains($inFunction->getName(), 'please')) {
	// if it's called from a function/method containing "please", it's okay
	return null;
}

return RestrictedUsage::create(
	errorMessage: sprintf(
		'Method %s::%s() is called from %s which does not say "please".',
		$methodReflection->getDeclaringClass()->getDisplayName(),
		$methodReflection->getName(),
		$inFunction !== null ? $inFunction->getName() : 'outside a function',
	),
	identifier: 'method.noPlease',
);

Extension implementing RestrictedMethodUsageExtension has to be registered in the configuration file:

	-
		class: App\PHPStan\MyExtension
		tags:
			- phpstan.restrictedMethodUsageExtension

Class names #

The RestrictedClassNameUsageExtension is called for standalone class name references like in “class extends”, “class implements”, various parameter and return types, PHPDoc references, but also for static method calls like Foo::doBar(), static property and class constants accesses. In total there are more than 25 locations this extension is called for.

To ease the writing of error messages and identifiers that would differentiate between these locations, this extension is called with an extra argument when compared to other Restricted Usage extensions.

namespace PHPStan\Rules\RestrictedUsage;

use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Rules\ClassNameUsageLocation;

interface RestrictedClassNameUsageExtension
{
	public function isRestrictedClassNameUsage(
		ClassReflection $classReflection,
		Scope $scope,
		ClassNameUsageLocation $location,
	): ?RestrictedUsage;
}

ClassNameUsageLocation object offers createMessage() and createIdentifier() methods so when the extension decides to return the RestrictedUsage object, the creation typically looks like this:

return RestrictedUsage::create(
	$location->createMessage(sprintf(
		'internal %s %s',
		strtolower($classReflection->getClassTypeDescription()), $classReflection->getDisplayName())
	),
	$location->createIdentifier(sprintf('internal%s', $classReflection->getClassTypeDescription())),
);

The passed message part in this case is internal class Foo and the identifier part internalClass. With these values ClassNameUsageLocation will create these message+identifier pairs:

  • PHPDoc tag @property references internal class Foo. / propertyTag.internalClass
  • Instantiation of internal class Foo. / new.internalClass
  • Class Bar implements internal class Foo. / class.implementsInternalClass

Extension implementing RestrictedMethodUsageExtension has to be registered in the configuration file:

	-
		class: App\PHPStan\MyExtension
		tags:
			- phpstan.restrictedClassNameUsageExtension

Properties #

The remaining extensions are all analogous to the one about methods so if you want to know more details, check out the documentation above.

RestrictedPropertyUsageExtension interface looks like this:

namespace PHPStan\Rules\RestrictedUsage;

use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ExtendedPropertyReflection;

interface RestrictedPropertyUsageExtension
{
	public function isRestrictedPropertyUsage(
		ExtendedPropertyReflection $propertyReflection,
		Scope $scope,
	): ?RestrictedUsage;
}

This extension is called for both instance property accesses like $foo->bar but also for static property accesses like Foo::$bar.

Extension implementing RestrictedPropertyUsageExtension has to be registered in the configuration file:

	-
		class: App\PHPStan\MyExtension
		tags:
			- phpstan.restrictedPropertyUsageExtension

Class constants #

RestrictedClassConstantUsageExtension interface looks like this:

namespace PHPStan\Rules\RestrictedUsage;

use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassConstantReflection;

interface RestrictedClassConstantUsageExtension
{
	public function isRestrictedClassConstantUsage(
		ClassConstantReflection $constantReflection,
		Scope $scope,
	): ?RestrictedUsage;
}

Extension implementing RestrictedClassConstantUsageExtension has to be registered in the configuration file:

	-
		class: App\PHPStan\MyExtension
		tags:
			- phpstan.restrictedClassConstantUsageExtension

Functions #

RestrictedFunctionUsageExtension interface looks like this:

namespace PHPStan\Rules\RestrictedUsage;

use PHPStan\Analyser\Scope;
use PHPStan\Reflection\FunctionReflection;

interface RestrictedFunctionUsageExtension
{
	public function isRestrictedFunctionUsage(
		FunctionReflection $functionReflection,
		Scope $scope,
	): ?RestrictedUsage;
}

This extension is called for traditional function calls like doBar(1, 2, 3), but also for first-class callables like doBar(...).

Extension implementing RestrictedFunctionUsageExtension has to be registered in the configuration file:

	-
		class: App\PHPStan\MyExtension
		tags:
			- phpstan.restrictedFunctionUsageExtension

Edit this page on GitHub

Theme
A
© 2025 PHPStan s.r.o.