Приведение типов в PHP: руководство разработчика

Раздел: Типизация в PHP -> Приведение типов

Приведение типов в PHP

Как эффективно привести значение к нужному типу?

Основной способ - явное приведение с помощью операторов в скобках перед значением: (int), (float), (string), (bool), (array), (object). Этот метод работает быстро и позволяет контролировать преобразование.

$str = "42.5";
$int = (int) $str; // 42
$float = (float) $str; // 42.5
$bool = (bool) $str; // true

Php приведение типов (приведение типов в php)

int(42)
float(42.5)
bool(true)

Проблема: При приведении строки, начинающейся с нецифрового символа, к числу получится 0 (кроме ведущих пробелов). Например, (int) "abc" -> 0. Это может привести к неожиданным результатам.

Решение: Перед приведением содержимое строки рекомендуется проверять с помощью is_numeric() или filter_var.

Как преобразовать строку в число с помощью функций?

Функции intval(), floatval(), strval() и boolval() делают то же самое, что и операторы, но могут принимать второй аргумент для intval (основание системы счисления).

$hex = "1A";
$dec = intval($hex, 16); // 26
int(26)

Проблема: intval с основанием 0 определяет систему автоматически (может быть неожиданно).

Как изменить тип переменной напрямую, без присваивания результата?

Функция settype(&$var, $type) изменяет тип переданной переменной и возвращает true/false. Она полезна, когда нужно преобразовать множество переменных или в циклах.

$val = "3.14";
settype($val, "float");
echo $val; // 3.14
3.14

Проблема: При неудачном преобразовании (например, settype($val, "int") для нечисловой строки) переменная станет 0, а функция вернет true. Нельзя отличить успех с нулем от неудачи.

Когда происходит автоматическое преобразование типов?

PHP неявно приводит типы при математических операциях, сравнениях (особенно ==), конкатенации строк, передаче аргументов в функции, возврате значений. Это удобно, но может быть источником ошибок.

$a = "10";
$b = 5;
echo $a + $b; // 15 (строка преобразуется в число)
15

Проблема: Сравнение "123abc" == 123 дает true, так как строка приводится к числу 123. Неожиданное поведение. Для строгого сравнения предназначен оператор ===.

Как привести массив к объекту или наоборот?

Оператор (object) для массива создает stdClass, где ключи становятся свойствами. (array) для объекта создает массив из свойств.

$arr = ["name" => "John", "age" => 30];
$obj = (object) $arr;
echo $obj->name; // John
$back = (array) $obj;
print_r($back);
John
Array ( [name] => John [age] => 30 )

Проблема: Приведение объекта другого класса к массиву преобразует только public свойства. Protected и private теряются или добавляются с null-байтами в именах.

Как работает приведение к булевому типу?

(bool) преобразует значение по правилам: false для 0, пустой строки, null, пустого массива, а также специального значения "0". Все остальное - true.

var_dump((bool) "0"); // false
var_dump((bool) "false"); // true (непустая строка)
var_dump((bool) []); // false
bool(false)
bool(true)
bool(false)

Проблема: Строка "false" - true, что может сбивать с толку. Явная проверка через === false или empty() позволяет избежать неожиданностей.

Что такое приведение к null (устарело)?

Ранее существовал оператор (unset), который приводил значение к null. В PHP 7.2 помечен устаревшим, в PHP 8 удален. Вместо него используется присваивание null или unset переменной.

// До PHP 7.2:
$a = (unset) $b; // $a = null, $b не меняется

Применение (unset) в новом коде не рекомендуется. Для обнуления переменной достаточно присвоить null.

Расширенные примеры приведения типов

Потеря точности при приведении больших чисел

Пример
$big = 12345678901234567890;
$f = (float) $big;
var_dump($f);
echo ($f === (float)$big ? "равны" : "не равны");
float(1.2345678901234568E+19)
не равны
Проблема: Число теряет точность из-за ограничений float. Для работы с большими целыми применяется int (если влезает в 64 бита) или bcmath.

Приведение строки с ведущими нулями и пробелами

Пример
$str = "  007 ";
$int = (int) $str;
echo $int; // 7
7
Проблема: Ведущие пробелы игнорируются, нули тоже. Для сохранения нулей следует применять строковый тип.

Приведение массива с числовыми ключами к объекту

Пример
$arr = [10, 20, 30];
$obj = (object) $arr;
var_dump($obj);
echo $obj->{0}; // 10
object(stdClass)#1 (3) { [0]=> int(10) [1]=> int(20) [2]=> int(30) }
10
Проблема: Доступ к свойствам с числовыми именами возможен только через фигурные скобки. Это неудобно.

Безопасное приведение с помощью filter_var

Пример
$val = "123abc";
$int = filter_var($val, FILTER_VALIDATE_INT);
if ($int === false) {
    echo "Не является целым числом";
} else {
    echo "Целое: $int";
}
Не является целым числом
Проблема: filter_var возвращает false при неудаче, что позволяет отличить нулевой результат от ошибки. Однако false может быть и при значении 0? Нет, 0 проходит валидацию, возвращает 0, не false.

Неявное приведение в условии if

Пример
$value = "0";
if ($value) {
    echo "выполнено";
} else {
    echo "не выполнено";
}
не выполнено
Проблема: Строка "0" приводится к false. Для проверки, определена ли переменная и не пуста, применяются isset() или empty().

Приведение типов при работе с PDO

Пример
// PDO по умолчанию возвращает строки даже для целых колонок
// Чтобы получить правильные типы, используйте fetch(PDO::FETCH_ASSOC) и затем явное приведение
$stmt = $pdo->query("SELECT id, name FROM users");
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$id = (int) $row['id']; // явное приведение
$name = (string) $row['name'];
Проблема: Если не приводить, то сравнение (int)$id == $row['id'] может дать true, но строгое === будет false. Типы следует проверять всегда.

Использование array_map для массового приведения

Пример
$strings = ["1", "2", "3"];
$ints = array_map('intval', $strings);
var_dump($ints); // [1,2,3]
array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
Проблема: array_map использует функцию обратного вызова. Можно передать 'intval', 'floatval', '(int)' нельзя. Для сложных правил лучше написать анонимную функцию.

Приведение типов в PHP - comments

En
Php приведение типов (php)