mixed — это псевдотип, добавленный в PHP 8, который указывает, что параметр, возвращаемое значение или свойство могут иметь любой тип. Тип mixed включает в себя все скалярные типы PHP, null , все объекты классов, callable и даже resource .
mixed эквивалентен Union-типу (типу пересечения/объединения) из:
string|int|float|bool|null|array|object|callable|resource
С появлением mixed теперь можно указывать mixed в качестве типа, когда параметры, возвращаемые значения и свойства классов могут быть абсолютно любого типа.
class Example {
public mixed $exampleProperty;
public function foo(mixed $foo): mixed {}
} mixed — это псевдотип
mixed представляет любой тип, с которым может работать PHP, поэтому вы не можете привести переменную к mixed — в этом просто нет смысла.
$foo = (mixed) $bar;
Кроме того, по тем же причинам функции is_mixed() не существует.
Функции gettype() и get_debug_type() также никогда не вернут mixed в качестве типа переменной.
mixed в объединении с другими типами
Поскольку mixed представляет все типы, mixed нельзя использовать в union-типах с другими типами:
function (mixed|FooClass $bar): int|mixed {} Оба указанных выше union-типа недопустимы и приведут к фатальной ошибке:
Fatal error: Type mixed can only be used as a standalone type in ... on line ...
mixed подразумевается, если тип не объявлен
Если у параметра функции или свойства класса не объявлен явный тип, теперь предполагается, что его тип — mixed .
Будьте внимательны при добавлении типа mixed во весь существующий код: в PHP 8 появились Union-типы, которые могут подойти лучше, поскольку позволяют быть более точными.
Что касается возвращаемых типов, отсутствие явно указанного возвращаемого типа эквивалентно mixed|void .
Однако учтите, что вы не можете объявить mixed|void в качестве возвращаемого типа, поскольку mixed запрещен в Union-типах.
Вариантность типов
Когда метод класса, возвращаемый тип или тип свойства переопределяются подклассом, соблюдается принцип подстановки Барбары Лисков (LSP).
Контравариантность: типы параметров mixed
Типы параметров функций могут быть «расширены» в дочернем классе или в реализации интерфейса, поскольку расширенный тип по-прежнему выполняет контракт интерфейса/родительского класса. Это означает, что параметры дочернего класса могут объявлять тип с помощью Union-типа, включающего больше типов, или имени класса, являющегося родительским для текущего класса.
Когда тип параметра объявлен как mixed , это практически исключает дальнейшую контравариантность, поскольку mixed уже включает в себя все типы, с которыми работает PHP. По возможности всегда выбирайте более конкретные типы, потому что как только вы помечаете тип параметра как mixed в публичном API, все дочерние классы должны быть способны обрабатывать смешанные типы.
Ковариантность: возвращаемые типы mixed
Если метод родительского класса объявил возвращаемый тип, отличный от mixed , дочерним классам будет запрещено объявлять mixed , поскольку это расширяет область возвращаемого типа и тем самым нарушает LSP.
class A {
public function foo(): mixed {}
}
class B extends A{
public function foo(): void {}
} Приведенный выше код приведет к фатальной ошибке:
Fatal error: Declaration of B::foo(): void must be compatible with A::foo(): mixed
Это связано с тем, что mixed не включает в себя тип void . Если возвращаемый тип не объявлен явно, предполагается, что это mixed|void .
Все следующие объявления разрешены:
class A {
public function foo() {}
public function bar() {}
public function baz(): mixed {}
}
class B extends A{
public function foo(): mixed {}
public function bar(): void {}
public function baz(): string {}
} - B::foo : Разрешено: сужает предполагаемый возвращаемый тип mixed|void метода A::foo .
- B::bar : Разрешено: сужает предполагаемый возвращаемый тип mixed|void метода A::bar .
- B::baz : Разрешено: сужает объявленный тип mixed .
Инвариантность: типы свойств mixed
Если тип свойства объявлен как mixed , этот тип нельзя опускать или изменять вообще.
Использование с void
PHP поддерживает псевдотип возвращаемого значения void , указывающий на то, что функция ничего не возвращает. Это эквивалентно отсутствию инструкции return или выражению return; без явного значения.
Тип void и mixed не могут быть объединены в union. Кроме того, mixed не включает void .
Nullable-типы mixed
Запрещено объявлять тип mixed как nullable, поскольку mixed уже включает в себя null .
Все следующие объявления недопустимы:
function foo(mixed|null $foo) {}
function foo(?mixed $foo) {}
function foo($foo): mixed|null {}
function foo($foo): ?mixed {} Все вышеперечисленные объявления вызовут фатальную ошибку:
Fatal error: Type mixed can only be used as a standalone type in ... on line ...
Практическое использование
Многие встроенные функции PHP принимают различные типы, которые теперь можно объявлять с помощью типа mixed . Однако для пользовательских функций зачастую лучше использовать конкретный тип или Union-тип.
Такие функции, как var_dump или get_debug_type() , могут объявлять свои параметры как mixed , поскольку по определению они принимают любой тип.
Если вы объявляете параметр, возвращаемый тип или свойство класса с типом mixed , имейте в виду, что mixed включает такие типы, как resource и callable , которые непросто сохранить, сериализовать, очистить (санитизировать) или отобразить.
Большинству пользовательских функций, которым нужно «принимать что угодно» (например, функциям логирования), лучше подойдут Union-типы, такие как string|int|float|bool|null|object|array .
Обратная совместимость
mixed является мягко зарезервированным словом начиная с PHP 7. До PHP 8 технически было возможно объявить класс с именем mixed , и это не вызывало никаких ошибок, предупреждений или замечаний. Стандарт PHPDoc широко использовал mixed в качестве объявления типа, поэтому крайне маловероятно, что даже в самых нестандартных кодовых базах найдется класс с именем mixed .
Попытка объявить класс с именем mixed в PHP 8 приведет к следующей ошибке:
Fatal error: Cannot use 'mixed' as class name as it is reserved in ... on line ...
Полифил
Эту функциональность невозможно реализовать через полифил, поскольку это встроенный внутренний тип. Если вы используете тип mixed где-либо в своем коде, убедитесь, что он всегда будет выполняться в среде PHP 8+.
Комментарии (0)
Пока нет комментариев — будьте первым.