Манипуляции с типами

PHP не требует явного определения типа при объявлении переменной. В этом случае тип переменной определяется значением, которое она хранит. То есть, если переменной $var присваивается значение типа строка (string), то $var изменит тип на строку (string). Если после этого переменной $var будет присвоено значение типа целое число (int), то она изменит тип на целое число (int).

В определённых контекстах PHP может попытаться автоматически преобразовать тип значения в другой. Существуют следующие различные контексты:

  • Числовой контекст
  • Строчный контекст
  • Логический контекст
  • Контекст целых чисел и строк
  • Сравнительный контекст
  • Контекст функций

Замечание: Когда значение нужно интерпретировать как другой тип, само значение не меняет тип.

Чтобы принудительно установить тип переменной, смотрите раздел Приведение типа. Чтобы изменить тип переменной, смотрите описание функции settype().

Числовой контекст

Контекст при использовании арифметического оператора.

В данном контексте, если один из операндов является числом с плавающей точкой (float) (или не интерпретируется как целое число (int)), оба операнда интерпретируются как число с плавающей точкой (float) и результатом будет число с плавающей точкой (float). В противном случае операнды будут интерпретированы как целое число (int) и результатом также будет целое число (int). Начиная с PHP 8.0.0, если один из операндов не может быть интерпретирован, выбрасывается ошибка TypeError.

Строчный контекст

Контекст при использовании функций echo, print, интерполяции строк или строкового оператора конкатенации.

В данном контексте значение будет интерпретироваться как строка (string). Если значение не может быть интерпретировано, выбрасывается ошибка TypeError. До версии PHP 7.4.0 выдавалась ошибка уровня E_RECOVERABLE_ERROR.

Логический контекст

Контекст при использовании условных операторов, тернарного оператора или логического оператора.

В данном контексте значение будет интерпретироваться как логическое значение (bool).

Контекст целых чисел и строк

Контекст при использовании побитовых операторов.

В данном контексте, если у всех операндов тип строка (string), результат также будет строкой (string). В противном случае операнды будут интерпретированы как целое число (int) и результат также будет целым числом (int). Начиная с PHP 8.0.0, если один из операндов не может быть интерпретирован, то будет выброшена ошибка TypeError.

Сравнительный контекст

Контекст при использовании оператора сравнения.

Преобразования типов, которые происходят в этом контексте, объясняются в таблице сравнения различных типов раздела Операторы сравнения.

Контекст функций

Контекст, когда значение передаётся типизированному параметру, свойству или возвращается из функции, в которой объявлен тип возвращаемого значения.

В этом контексте значение должно быть значением данного типа. Существуют два исключения, первое: если тип значения – целое число (int), а объявленный тип - число с плавающей точкой (float), то целое число преобразуется в число с плавающей точкой. Второй: если объявленный тип является скалярным типом, значение преобразуется в скалярный тип и режим строгой типизации активен (по умолчанию), значение может быть преобразовано в допустимое скалярное значение. Описание такого поведения смотрите ниже.

Внимание

Встроенные функции автоматически подставляют null к скалярным типам, это поведение УСТАРЕЛО в PHP 8.1.0.

Принудительная типизация с простым объявлением типов

  • Объявление типа bool: значение интерпретируется как логическое значение (bool).
  • Объявление типа int: значение интерпретируется как целое число (int), если преобразование хорошо определено. Например, строка является числовой строкой.
  • Объявление типа float: значение интерпретируется как число с плавающей точкой (float) если преобразование хорошо определено. Например, строка является числовой строкой.
  • Объявление типа string: значение интерпретируется как строка (string).

Принудительная типизация с объединением типов

При выключенном strict_types, объявления скалярных типов подвергаются ограниченному неявному приведению типов. Если точный тип значения не является частью объединения, то целевой тип выбирается в следующем порядке предпочтения:

  1. int
  2. float
  3. string
  4. bool
Если тип и существует в объединении и значение может быть приведено к этому типу в соответствии с существующей семантикой проверки типов PHP, то выбирается этот тип. В противном случае выбирается следующий тип.

Предостережение

В качестве исключения, если значение является строкой, а целое число (int) и число с плавающей точкой (float) являются частью объединения, предпочтительный тип определяется существующей семантикой числовой строки. Например, для "42" выбирается целое число (int), а для "42.0" выбирается число с плавающей точкой (float).

Замечание:

Типы, не входящие в приведённый выше список предпочтений, не являются объектами для неявного приведения. В частности, не происходит неявного приведения к типам null, false и true.

Пример #1 Пример принудительного включения типов в состав объединения

<?php
// int|string
42 --> 42 // точный тип
"42" --> "42" // точный тип
new ObjectWithToString --> "Результат __toString()"
// объект не совместим с int, переход к string
42.0 --> 42 // float совместимый с int
42.1 --> 42 // float совместимый с int
1e100 --> "1.0E+100" // float слишком велик для типа int, переход к string
INF --> "INF" // float слишком велик для типа int, переход к string
true --> 1 // bool совместимый с int
[] --> TypeError // массив не совместим с int или string

// int|float|bool
"45" --> 45 // int числовая строка
"45.0" --> 45.0 // float числовая строка

"45X" --> true // не числовая строка, переход к bool
"" --> false // не числовая строка, переход к bool
"X" --> true // не числовая строка, переход к bool
[] --> TypeError // массив не совместимый с int, float или bool
?>

Приведение типов

Приведение типа преобразует значение к выбранному типу, записывая тип в круглых скобках перед преобразуемым значением.

<?php
$foo
= 10; // $foo - это целое число
$bar = (bool) $foo; // $bar - это логическое значение
?>

Допускаются следующие приведения типов:

  • (int) - приведение типа к целому числу (int)
  • (bool) - приведение типа к логическому значению (bool)
  • (float) - приведение типа к числу с плавающей точкой (float)
  • (string) - приведение типа к строке (string)
  • (array) - приведение типа к массиву (array)
  • (object) - приведение типа к объекту (object)
  • (unset) - приведение типа к NULL

Замечание:

(integer) является псевдонимом приведения типа (int). (boolean) является псевдонимом приведения типа (bool). (binary) является псевдонимом приведения типа (string). (double) и (real) являются псевдонимами приведения типа (float). Эти приведения не используют каноническое имя типа и не рекомендуются.

Внимание

Псевдоним приведения типа (real) устарел, начиная с PHP 8.0.0.

Внимание

Приведение типа (unset) устарело, начиная с версии PHP 7.2.0. Обратите внимание, что приведение (unset) равносильно присвоению переменной или вызову значения NULL. Приведение (unset) удалено в PHP 8.0.0.

Предостережение

Приведение типа (binary) и префикс b существуют для прямой поддержки. В настоящее время (binary) и (string) идентичны, однако это может измениться и на это не следует полагаться.

Замечание:

Пробелы игнорируются в круглых скобках при приведении типа. Таким образом, следующие два приведения типов эквивалентны:

<?php
$foo
= (int) $bar;
$foo = ( int ) $bar;
?>

Приведение строк (string) и переменных к бинарным строкам (string):

<?php
$binary
= (binary) $string;
$binary = b"binary string";
?>

Замечание: Вместо приведения переменной к типу строка (string) можно также заключить переменную в двойные кавычки.

<?php
$foo
= 10; // $foo является целым числом
$str = "$foo"; // $str является строкой
$fst = (string) $foo; // $fst также является строкой

// Выводит, что "они одинаковые"
if ($fst === $str) {
echo
"они одинаковые";
}
?>

Может быть неочевидно, что именно произойдёт при преобразовании между определёнными типами. Для получения дополнительной информации смотрите эти разделы:

Замечание: Поскольку PHP поддерживает индексацию в строках (string) с помощью смещения, используя тот же синтаксис, что и индексация в массивах (array), следующий пример справедлив для всех версий PHP:

<?php
$a
= 'car'; // $a является строкой
$a[0] = 'b'; // $a по-прежнему является строкой
echo $a; // bar
?>
Дополнительную информацию смотрите в разделе Доступ к символу в строке и его изменение.