В PHP восемь типов, которыми пользуются каждый день: int, float, string, bool, array, object, null и ещё callable для функций, которые передаются как значения. У переменной нет фиксированного типа; тип есть у её текущего значения. var_dump($x) показывает и тип, и значение, а gettype($x) возвращает тип строкой.
Первый столбец это gettype(), второй get_debug_type(). Замените значение своим и запустите снова. В нескольких именах они расходятся: gettype по историческим причинам пишет integer, double и boolean, а get_debug_type использует имена из объявлений типов (int, float, bool) и для объекта возвращает имя класса.
Типы PHP коротко
| Тип | Пример | Примечания |
|---|---|---|
int | 42, -7, 0x1A, 1_000_000 | целые числа, на современных системах 64-битные |
float | 3.14, 1.5e3 | дробные числа, неточные, как и в любом языке |
string | "hi", 'hi' | последовательность байтов, а не символов |
bool | true, false | регистр не важен (TRUE тоже работает) |
array | [1, 2], ["a" => 1] | упорядоченный словарь: список и словарь в одном |
object | new User(), new stdClass() | экземпляр класса |
null | null | единственное значение типа null; также "значение не задано" |
callable | 'strlen', fn($x) => $x * 2 | всё, что можно вызвать |
iterable | массив или объект Traversable | то, что принимает foreach |
resource | результат fopen() | дескриптор чего-то вне PHP |
Просмотр значений через var_dump
var_dump это инструмент, чтобы увидеть, что у вас на самом деле. Он печатает тип, значение, а для строк длину в байтах:
echo напечатал бы 10 для первых трёх и скрыл бы разницу. Длина в string(5) "café" считается в байтах, поэтому strlen и mb_strlen расходятся на не-ASCII тексте.
Целые и дробные числа
Целое число это число без дробной части. В литералах можно использовать подчёркивания для читаемости, а также шестнадцатеричную, восьмеричную и двоичную запись. Float это любое число с десятичной точкой или экспонентой, и, как в любом языке, большинство десятичных дробей он хранит приближённо:
Никогда не сравнивайте float через ==; сравнивайте разницу с небольшим допуском или сначала округлите обе стороны. Деньги храните в целых копейках или центах.
Логический тип и какие значения ложны
bool это true или false. Там, где PHP ожидает условие (if, while, !), любое значение приводится к bool, и ложным считается короткий список значений: false, 0, 0.0, "", "0", [] и null. Всё остальное истинно. Таблица показывает для каждого значения его тип, приведение к bool и то, числовое ли оно:
| $x | gettype | bool | is_numeric |
|---|---|---|---|
| 0 | |||
| 1 | |||
| -1 | |||
| 0.0 | |||
| 1.5 | |||
| "0" | |||
| "" | |||
| " " | |||
| "0.0" | |||
| "10" | |||
| "1e1" | |||
| "abc" | |||
| "null" | |||
| true | |||
| false | |||
| null | |||
| [] | |||
| [0] |
Неожиданны "0.0", " " и "null": все три непустые строки, отличные от "0", поэтому они истинны, и if ($value) выполнит для них своё тело.
Массивы, объекты и null
Массив хранит любые значения под целочисленными или строковыми ключами. Объект это экземпляр класса; stdClass это пустой класс PHP для быстрых объектов, а (object) превращает массив в объект. null означает "нет значения":
Проверка типа функциями is_*
Для каждого типа есть функция проверки, которая возвращает true или false. is_numeric отличается от is_int: она принимает и числовые строки, что и нужно при проверке данных из формы.
Есть и другие: is_bool, is_array, is_object, is_null, is_callable, is_iterable, а для конкретного класса $x instanceof ClassName.
Неявное приведение и строгие типы
PHP автоматически приводит типы, когда оператору нужен другой тип. Числовая строка в арифметике становится числом, а . превращает числа в строки. Строку, которая совсем не похожа на число, сложить нельзя, и PHP 8 выбрасывает TypeError:
Типизированные параметры тоже приводят значения, если файл не начинается с declare(strict_types=1);. Тогда вызов с неверным скалярным типом завершается ошибкой, а не приведением:
Чтобы привести тип намеренно, используйте приведение: (int) "42", (float) "3.5", (string) 10, (bool) "0". На странице о приведении типов разобраны все приведения и их пограничные случаи.
Частая ошибка: сравнение разных типов через ==
Поскольку == приводит типы перед сравнением, два значения разных типов могут оказаться "равными" так, что это порождает ошибки, например "1e1" == "10" (оба это число 10) или null == false. Используйте ===, которое требует ещё и совпадения типа, если приведение вам не нужно:
PHP 8 исправил худший случай: "abc" == 0 раньше было true, а теперь false, потому что нечисловая строка сравнивается как строка. Полные таблицы есть на странице об операторах сравнения.
Часто задаваемые вопросы
Как проверить тип переменной в PHP?
var_dump($x) печатает тип и значение, например int(5). gettype($x) возвращает имя типа строкой ("integer"), а get_debug_type($x) современное имя ("int" или имя класса для объектов). Чтобы проверить один конкретный тип, используйте is_int, is_string, is_array и другие функции is_*.
Почему gettype возвращает "double" для float?
По историческим причинам gettype() называет float "double", а целые "integer". get_debug_type(), добавленная в PHP 8, возвращает "float" и "int", те же имена, что пишутся в объявлениях типов.
Какие значения в PHP считаются false?
При приведении к bool false дают: false, 0, 0.0, "", "0", [] и null. Всё остальное true, включая "0.0", " " и "false".
Какое максимальное целое число в PHP?
PHP_INT_MAX, на 64-битных системах это 9223372036854775807. При выходе за него значение не переполняется по кругу: результат становится float и теряет точность.
PHP это язык со строгой или слабой типизацией?
PHP типизирован динамически и по умолчанию приводит типы, когда может ("10" + 5 равно 15). С declare(strict_types=1); в начале файла вызовы типизированных функций в этом файле отвергают неверные скалярные типы с TypeError, а не приводят их.