/
Программирование
/
Курс PHP
/

Слабая типизация

PHP: Слабая типизация

Нам известно про два разных типа данных: числа и строки. Мы могли складывать числа, потому что операция сложения — это операция для типа «числа». А что, если применить эту операцию к числу и строке?

<?php

print_r(1 + '7'); // => 8

'7' — это строка, а не число, при этом интерпретатор PHP выдал ответ 8, как если бы мы складывали два числа. Когда PHP видит несоответствие типов, он сам пытается преобразовать информацию. В данном случае он преобразовал строку '7' в число 7, а потом сложил 1 и 7.

Слабая типизация

Не все языки так делают. PHP — это язык со слабой типизацией. Он знает о существовании разных типов (числа, строки и другие), но относится к их использованию не строго и пытается преобразовывать данные, когда это кажется ему разумным.

Обратите внимание: оператор + в PHP всегда означает арифметику, а для соединения строк есть отдельный оператор — конкатенация .. Поэтому в выражении 1 + '7' PHP превращает строку в число, а в выражении 1 . '7' — наоборот, число в строку:

<?php

print_r(1 + '7'); // => 8
print_r(1 . '7'); // => 17
1 + '7'  →  8     (строка превратилась в число, сложение)
'7' - 1  →  6     (строка превратилась в число, вычитание)
1 . '7'  →  '17'  (число превратилось в строку, конкатенация)

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

<?php

print_r(1 + 'seven');
// TypeError: Unsupported operand types: int + string

Но стоит строке начинаться с цифры — и PHP снова попробует «угадать»: выражение 1 + '7 самураев' вернет 8, лишь выдав предупреждение.

А как в строгих языках?

В языках со строгой (сильной) типизацией сложить число со строкой не получится — программа остановится с ошибкой. Например, в Python или Ruby выражение 1 + '7' приведет к ошибке типов: язык требует, чтобы программист явно указал, как преобразовать данные.

При этом языки не делятся ровно на два лагеря — «строгие» и «слабые». Корректнее говорить, что у разных языков разная степень строгости: где-то неявных преобразований почти нет, а где-то их много. PHP находится у «слабого» края этой шкалы, хотя с каждой новой версией становится строже.

Статическая и динамическая типизация

Есть и другое, отдельное понятие — статическая и динамическая типизация. Оно описывает, когда проверяются типы. PHP относится к динамически типизированным языкам: типы проверяются во время работы программы. В статически типизированных языках проверка обычно происходит раньше, еще до запуска кода, на стадии компиляции.

Важно не путать две вещи:

  • статическая/динамическая типизация отвечает на вопрос «когда проверяются типы»;
  • сильная/слабая типизация отвечает на вопрос «что произойдет, если смешать разные типы без явного преобразования».

Это независимые свойства. PHP — язык динамический и слабо типизированный.

Почему PHP такой

PHP был создан для интернета, а в интернете вся информация — это строки. Даже когда мы вводим на сайте номер телефона или год рождения, на сервер эта информация поступает не как числа, а как строки. Поэтому авторы языка решили, что автоматически преобразовывать типы — правильно и удобно.

Удобство есть, но у него высокая цена. На практике неявные преобразования создают множество ошибок и проблем, которые трудно найти: код может иногда работать, а иногда не работать. Это зависит от того, «повезло» ли в конкретном случае с автоматическим преобразованием. Программист замечает это не сразу.

В дальнейших заданиях мы будем встречаться с таким поведением не раз. Часто будет возникать вопрос «почему мой код работает не так, как я ожидаю?». Слабая типизация красной нитью проходит сквозь всю разработку на PHP. Чуть позже в этом модуле мы научимся преобразовывать типы явно — и делать это всегда осознанно.

Задание

В игре два игрока. Первый набрал 7 очков, второй потерял очки: выражение (-8 - -2) описывает его результат. Посчитайте разницу и выведите на экран: 7 - (-8 - -2).

Попробуйте сделать число 7 не числом, а строкой: '7' - (-8 - -2). Сработает ли такой код? Поэкспериментируйте с другими числами тоже.

Полезное

Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются