Перейти к содержимому
Теория · Переменные и типы · урок 4 из 6

Преобразование типов

В прошлом уроке у каждого значения появилась наклейка с типом. Настоящая банка никогда не переделывает своё содержимое: варенье в ней само не станет компотом. А PHP переделывает: когда операции нужен другой тип, он сам преобразует значение, которое взял из банки, а в самой банке всё остаётся как было.

Давайте посмотрим, что получится, если сложить строку с числом:

PHP
<?php

$text = '5';
$sum = $text + 3;
var_dump($text); // string(1) "5"
var_dump($sum); // int(8)

Разберём по строкам:

  1. В $text лежит строка '5'.
  2. Сложению нужны числа, поэтому PHP превращает строку '5' в число 5, и в $sum попадает 8.
  3. var_dump($text) показывает, что сама переменная $text не изменилась: в ней всё ещё строка.
  4. var_dump($sum) печатает int(8): результат сложения — число.

Такое автоматическое преобразование называют жонглированием типами. PHP приводит значение к типу, который нужен операции, и не трогает переменную, из которой это значение взял.

Явное приведение

Иногда тип нужно поменять самому. Для этого перед значением пишут нужный тип в скобках — это приведение типа:

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' целиком состояла из числа. А если в строке есть буквы?

PHP
echo '12 apples' + 1, "\n"; // ✗
echo 'apples' + 1, "\n"; // ✗

Число в начале строки

Первая строка выполняется: PHP берёт 12, прибавляет 1 и печатает 13. Но перед этим он выдаёт предупреждение, потому что '12 apples' — не целиком число:

TEXT
Warning: A non-numeric value encountered

Строка без числа

Во второй строке в 'apples' числа нет вовсе. PHP отказывается складывать такую строку с числом и останавливает скрипт на второй строке кода:

TEXT
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:

PHP
$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 — как пустую строку.