Как работает динамическая типизация в PHP?

«Как работает динамическая типизация в PHP?» — вопрос из категории PHP Core, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Основные принципы:

  1. Тип привязан к значению, а не к переменной.

    $value = 10;      // $value теперь содержит integer
    $value = 'Hello'; // $value теперь содержит string
    $value = 3.14;    // $value теперь содержит float (double)
    $value = [];      // $value теперь содержит array
  2. Автоматическое (неявное) преобразование типов (type juggling). PHP пытается автоматически преобразовать типы в контексте операции.

    $sum = "5" + 2;       // Результат: 7 (integer). Строка "5" преобразована в число 5.
    $result = "Hello" . 123; // Результат: "Hello123" (string). Число 123 преобразовано в строку.
    $isEqual = 0 == "0";   // Результат: true. Строка "0" преобразована в число 0 для сравнения.
  3. Строгое сравнение для контроля типов. Чтобы избежать неожиданных преобразований при сравнении, используется оператор === (строгое равенство) или !==.

    0 == "0";   // true (значения эквивалентны после приведения)
    0 === "0";  // false (разные типы: integer vs string)
    
    false == "";    // true
    false === "";   // false
  4. Явное преобразование типов (type casting). Можно явно указать, в какой тип нужно преобразовать значение.

    $number = (int) "42 apples"; // $number = 42 (берется начальная числовая часть)
    $text = (string) 3.14;       // $text = "3.14"
    $bool = (bool) 1;            // $bool = true
    $array = (array) 'test';     // $array = [0 => 'test']

Практический пример с функцией:

function add($a, $b) {
    // PHP попытается преобразовать $a и $b к числам для сложения
    return $a + $b;
}

echo add(5, "10");     // 15 ("10" -> 10)
echo add(5, "10 apples"); // 15 ("10 apples" -> 10)
echo add(5, "apples");   // 5 ("apples" -> 0) + Warning

Эволюция в сторону строгости: Хотя PHP остается динамически типизированным языком, в современных версиях добавлены возможности для повышения надежности:

  • Строгий режим (declare(strict_types=1)): Включается в начале файла. Запрещает неявное преобразование типов для скалярных аргументов функций и возвращаемых значений.

    declare(strict_types=1);
    
    function sum(int $a, int $b): int {
        return $a + $b;
    }
    
    echo sum(5, 10);     // 15
    echo sum(5, "10");   // TypeError в строгом режиме! Без режима было бы 15.
  • Подсказки типов (type hints): Можно указывать ожидаемые типы для аргументов функций, возвращаемых значений и свойств классов (начиная с PHP 7.4). Это не меняет динамическую природу языка, но помогает статическим анализаторам и улучшает читаемость кода.

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