Преобразование типов
В прошлом уроке у каждого значения появилась наклейка с типом. Настоящая банка никогда не переделывает своё содержимое: варенье в ней само не станет компотом. А PHP переделывает: когда операции нужен другой тип, он сам преобразует значение, которое взял из банки, а в самой банке всё остаётся как было.
Давайте посмотрим, что получится, если сложить строку с числом:
<?php
$text = '5';
$sum = $text + 3;
var_dump($text); // string(1) "5"
var_dump($sum); // int(8)Разберём по строкам:
- В
$textлежит строка'5'. - Сложению нужны числа, поэтому PHP превращает строку
'5'в число5, и в$sumпопадает8. var_dump($text)показывает, что сама переменная$textне изменилась: в ней всё ещё строка.var_dump($sum)печатаетint(8): результат сложения — число.
Такое автоматическое преобразование называют жонглированием типами. PHP приводит значение к типу, который нужен операции, и не трогает переменную, из которой это значение взял.
Явное приведение
Иногда тип нужно поменять самому. Для этого перед значением пишут нужный тип в скобках — это приведение типа:
var_dump((int) 3.9); // int(3)
var_dump((int) '12 apples'); // int(12)
var_dump((int) 'apples'); // int(0)
var_dump(intval('42')); // int(42)
var_dump((float) '3.5'); // float(3.5)
var_dump((string) 42); // string(2) "42"
var_dump((string) true); // string(1) "1"
var_dump((string) false); // string(0) ""
var_dump((string) null); // string(0) ""
var_dump((bool) 0); // bool(false)
var_dump((bool) 'abc'); // bool(true)Разберём каждое приведение отдельно.
(int) и intval
Приведение к целому числу работает так:
- у дробного числа отбрасывается дробная часть, без округления:
(int) 3.9— это3; - из строки берутся цифры в её начале:
(int) '12 apples'— это12; - строка без цифр в начале даёт
0; - функция
intvalделает то же самое:intval('42')— это42.
Строку приведение читает без ошибок и предупреждений. То, что прочитать не удалось, оно молча отбрасывает.
(float)
Читает из строки дробное число: (float) '3.5' — это 3.5. Правила для строк те же, что у (int), только дробная часть сохраняется.
(string)
Превращает значение в текст:
- число
42становится строкой'42'; trueстановится строкой'1';falseиnullстановятся пустой строкой''.
(bool)
Даёт логическое значение: (bool) 0 — это false, а (bool) 'abc' — true.
Строка, которая не число
В первом примере строка '5' целиком состояла из числа. А если в строке есть буквы?
echo '12 apples' + 1, "\n"; // ✗
echo 'apples' + 1, "\n"; // ✗Число в начале строки
Первая строка выполняется: PHP берёт 12, прибавляет 1 и печатает 13. Но перед этим он выдаёт предупреждение, потому что '12 apples' — не целиком число:
Warning: A non-numeric value encounteredСтрока без числа
Во второй строке в 'apples' числа нет вовсе. PHP отказывается складывать такую строку с числом и останавливает скрипт на второй строке кода:
Fatal error: Uncaught TypeError: Unsupported operand types: string + intЗдесь видна разница между приведением и жонглированием. (int) 'apples' молча даёт 0, а 'apples' + 1 — это ошибка TypeError. На собеседовании любят спрашивать, что дают '5' + 3 и 'apples' + 1: ответ — 8 и TypeError.
Что печатает echo
echo перед выводом превращает каждое значение в строку — по тем же правилам, что (string):
- числа печатаются цифрами:
7 / 2выводится как3.5, а9.0— как9; trueпечатается как1;falseиnullстановятся пустой строкой, и на экране не появляется ничего.
Частая ошибка
Логическое значение напечатали через echo:
$isPaid = false;
echo 'paid: ', $isPaid, "\n"; // ✗Программа печатает paid: и больше ничего — ни ошибки, ни предупреждения. Значение false превратилось в пустую строку, и на экране его не видно. Чтобы увидеть логическое значение, печатайте его через var_dump: var_dump($isPaid); выведет bool(false).
Главное
- Когда операции нужен другой тип, PHP сам преобразует значение, а переменная при этом не меняется.
- Приведение
(int),(float),(string),(bool)читает строку молча:(int) '12 apples'— это12. - В арифметике строка с числом в начале даёт
Warning, а строка без числа — ошибкуTypeError. echoпечатаетtrueкак1, аfalseиnull— как пустую строку.