Nette Utils 3.2 with PHP 8.1 support and Type

3 years ago by David Grudl  

Nette libraries always support new PHP versions far in advance. The Nette Utils 3.2 package is now ready for PHP 8.1. What has changed?

Of all the new features in PHP 8.1, the biggest impact on Nette Utils is the introduction of intersection types, specifically for the Reflection class. Its main purpose is to fix the shortcomings of the native reflection classes and to unify behavior across PHP versions.

The trio of methods getParameterType(), getPropertyType() and getReturnType(), which are used to find the type of parameter, property or return value, was created at a time when PHP had only simple types that returned these methods as strings. It no longer deals with union and intersection types. To fully embrace the capabilities of the PHP type system, a new class Nette\Utils\Type was created. This replaces the above methods with Type::fromReflection(), that returns an object Type instead of a string:

use Nette\Utils\Type;

class MyClass
{
	public ?self $foo;
}

$prop = new ReflectionProperty(MyClass::class, 'foo');
$type = Type::fromReflection($prop);
echo $type;                  // '?MyClass'
echo $type->getSingleName(); // 'MyClass'
$type->isUnion();        // true
$type->isIntersection(); // false
$type->isBuiltin();      // false
$type->isClass();        // true

The usage is not only reflection-specific, but we can also create types according to textual notation:

$type = Type::fromString('Foo&Bar');
echo $type;              // 'Foo&Bar'
$type->isIntersection(); // true

A handy function allows() checks the compatibility of types. For example, it allows to check whether a value of a certain type could be passed as a parameter.

$type = Type::fromString('string|null');
$type->allows('string'); // true
$type->allows('null');   // true
$type->allows('Foo');    // false

$type = Type::fromString('mixed');
$type->allows('null');   // true

This class is also backported to Nette Utils v3.1.