PHP 8.0: New mixed pseudo type

mixed is a pseudo type added in PHP 8 that conveys the type of the parameter/return/property can be of any type. The mixed type includes all scalar types in PHP, null, all class objects, callables, and even resources.

blended is equivalent to a Union Type of:

string|int|float|bool|null|array|object|callable|resource

With mixed, it is now possible to declare mixed as the type when parameters, returns, and class properties can be of any type

. class Example { public mixed $exampleProperty; public function foo(mixed $foo): mixed {} } mixed is a mixed

pseudo

type

representing any type PHP can handle, and therefore you can’t convert a variable to mixed because it just doesn’t make sense.

$foo = $bar (mixed);

Also, there is no is_mixed() function for the same reasons.

The gettype() and get_debug_type() functions will never return mixed as the type of a variable either.

mixed in union with other types Because blended

represents all types, blended cannot be used in conjunction with other types:

function (mixed|

FooClass $bar): int|mixed {} The

above two join types are not allowed and will result in a

fatal error: Fatal error: The mixed type can only be used as an independent type in … Online…

Mixed

is assumed when no type is declared

When a function parameter or class property has no explicit type declared, the type is now assumed to be mixed.

Note when you add mixed types to all your existing code; PHP 8 has join types that might be more suitable because join types allow you to be more specific.

For return types

, the lack of an explicit return type equals mixed|void.

However, note that you cannot declare mixed|void as a return type because mixed is not allowed in a join type

.

Type variation

When a class method, a return type, or a property type is

replaced by a subclass, the Liskov substitution principle is respected

.

Contravariance: Mixed

parameter types

Function parameter types can be “extended” in a child class or in an interface implementation because the extended type still fulfills the interface/parent class contract. This means that child class parameters can declare a type with a union type that includes more types or a class name that is the parent of the current class.

When a parameter type is declared as mixed, this virtually avoids further contravariance because mixed includes all the types that PHP works with. If possible, always opt for more specific types because once you mark a parameter type as mixed in a public API, all child classes should be able to deal with mixed types.

Covariance

: mixed return types

If a primary class method has declared a return type other than mixed, child classes will not be able to declare mixed because it extends the scope of the return type, thus breaking LSP.

class A { public function foo(): mixed {} } class B extend A{ public function foo(): void {} }

This will result in a fatal error:

Fatal error: Declaration of B::foo(): void must support A::foo(): mixed

This is because mixed does not include the void type. If a return type is not explicitly declared, it is assumed to be mixed|void.

All of the

following declarations are allowed

: class A { public function foo() {} public function bar() {} public function baz(): mixed {} } class B extend A{ public function foo(): mixed {} public function bar(): void {} public function baz(): string {} } B::foo: Allowed: reduces the assumed mixed|void return type of A::

    foo. B::bar: Allowed: Reduces the

  • assumed mixed|void return type of A
  • :: slash
  • . B::

  • baz: Allowed: Reduces the declared mixed type.

Invariance: mixed property types

If a property type is declared as mixed, this type cannot be omitted or changed at all

.

Use with void

PHP supports the pseudo return type void to indicate that the function will not return anything. This amounts to the lack of a declaration of return, or return; without setting an explicit value.

The null and mixed type cannot be in a union. More mixed does not include null.

Mixed nullable types

It

is not allowed to declare the mixed type as voidable because mixed includes null. Not

all of the following

declarations are allowed: function foo(mixed|null $foo) {} function foo(?mixed $foo) {} function foo($foo): mixed|null {} function foo($foo): ?mixed {} All of

the above declarations will generate a fatal error: Fatal error:

The mixed type can only be used as an independent type in … Online…

Practical use

Many internal PHP functions accept several types, which can now be declared with the mixed type. However, for user-ground functions, it is often better to use a specific type or type of Junction.

Functions var_dump or get_debug_type() can declare their parameters as mixed because these functions accept any type by definition

.

If you declare a class type/return parameter as a mixed type, note that mixed includes types such as resource and callable, which are not easily stored, serialized, conditioned, or displayed.

Most user functions that need to “accept anything”, such as registry functions, are better off with a union type such as string|int|float|bool|null|object|array.

Mixed backward compatibility

is reserved since PHP 7. Until PHP 8, it is technically possible to declare a mixed-named class, and it will not generate errors, warnings, or warnings. The PHPDoc standard is widely used mixed as a type declaration, so it is highly unlikely that even the wildest codebase out there will declare a mixed-named class.

When trying to declare a class with the mixed name in PHP 8, the following error occurs:

Fatal error: Cannot use ‘mixed’ as class name as it is reserved in … Online…

Polyfill

It is not possible to polyfill this functionality because it is an internal type. If you use the mixed type anywhere in your code, make sure it will always run on a PHP 8+ platform.

Related changes

  • Junction types
  • New stringable interface

RFC discussion implementation