Полное руководство по типам данных в PHP 7: от основ до тонкостей
Типы данных в PHP 7: обзор и практика
Основной подход к работе с типами данных в PHP 7 - это применение строгой типизации (declare(strict_types=1)) и явных объявлений типов для аргументов функций, возвращаемых значений и свойств классов (начиная с PHP 7.4). Такая практика делает код самодокументируемым, снижает количество ошибок, связанных с неожиданным приведением типов, и упрощает отладку.
Пример объявления типов в функции:
<?php
declare(strict_types=1);
function sum(int $a, int $b): int {
return $a + $b;
}
echo sum(10, 20); // 30
Php check type (проверка типа переменной в php)
Если передать не целое число, например sum('10', 20), при строгой типизации возникнет TypeError, что предотвращает скрытые баги. Это наиболее эффективное решение для создания надёжных приложений.
Типичные ошибки:
- Пропуск declare(strict_types=1) - тогда PHP автоматически приводит типы (например, строку в число), что может маскировать ошибки.
- Использование mixed (доступно с PHP 8) в PHP 7 недопустимо; для гибких типов применяют iterable или документирование через PHPDoc.
Как проверить тип переменной во время выполнения?
Использование функций is_* (is_int, is_string, is_array и т.д.) и gettype(). Этот вариант полезен, когда тип заранее не известен, например, при обработке данных из внешних источников.
$value = '42';
if (is_numeric($value)) {
$intValue = (int)$value;
echo "Преобразовано в целое: ".$intValue;
}Of type string is deprecated php (предупреждение об устаревании типа string в php)
Функция gettype() возвращает строку с названием типа, но её не стоит использовать для логики из-за низкой производительности.
Проблема: is_numeric() принимает числа в строковом формате ('42', '3.14', '0xFF') - это может привести к неожиданным результатам. Лучше применять filter_var() с фильтрами FILTER_VALIDATE_INT и FILTER_VALIDATE_FLOAT.
Как преобразовать один тип в другой без потери данных?
Явное приведение типов (cast) с помощью операторов (int), (float), (string), (bool), (array), (object), (unset) и функции settype() (меняет исходную переменную). Для безопасного преобразования строк в числа лучше использовать intval() и floatval().
$price = '19.99';
$priceFloat = (float)$price; // 19.99
$priceInt = (int)$price; // 19 (отбрасывает дробную часть)
settype($price, 'float'); // $price становится 19.99Php mime type (mime-типы в php)
Случаи использования: подготовка данных для математических операций, приведение к нужному типу перед передачей в строго типизированные функции.
Ошибка: приведение строки, содержащей нечисловые символы ('100abc'), к int даст 100, отбросив 'abc'. Это часто бывает неожиданным. Рекомендуется предварительно валидировать строку регулярным выражением или filter_var.
Как работать со специальными типами null и resource?
Тип null - это значение null. Проверить на null можно оператором === или функцией is_null(). Тип resource - это внешний ресурс (файл, сокет, изображение). Для его проверки используйте is_resource(). Закрытие ресурса обязательно, иначе возможна утечка.
$handle = fopen('file.txt', 'r');
if (is_resource($handle)) {
// работа с файлом
fclose($handle);
}Php set type (функция settype() в php)
В современных приложениях ресурсы часто заменяют объектами (например, SplFileObject), которые управляют жизненным циклом автоматически.
Типичная ошибка: забыть закрыть ресурс, что приводит к блокировке файла или исчерпанию соединений.
Как объявить возвращаемый тип iterable или callable?
В PHP 7 появились псевдотипы iterable (массив или объект, реализующий Traversable) и callable (функция, метод, замыкание). Они позволяют строго задать ожидаемый тип аргумента или возврата.
function iterate(iterable $items): void {
foreach ($items as $item) {
echo $item;
}
}
iterate([1,2,3]); // OK
function execute(callable $callback): void {
$callback();
}
execute(function() { echo 'Hello'; });
Случаи использования: коллекции, итераторы, колбэки для событий.
Проблема: передача массива в iterable работает, но объект без Traversable вызовет TypeError. Для callable нельзя передать строку с именем функции, если она не определена.
Дополнительные примеры работы с типами в PHP 7
Ниже приведены расширенные и неочевидные примеры, демонстрирующие поведение типов в различных ситуациях.
1. Сравнение с плавающей точкой (float)
PHP 7 использует IEEE 754, поэтому сравнение чисел с плавающей точкой на равенство может давать неверные результаты из-за погрешности.
$a = 0.1 + 0.2;
$b = 0.3;
var_dump($a === $b); // bool(false)
// Решение: сравнивать с эпсилоном
$epsilon = 1e-10;
var_dump(abs($a - $b) < $epsilon); // bool(true)
bool(false) bool(true)
2. Целочисленное переполнение в 64-битной системе
PHP 7 на 64-битных платформах поддерживает целые числа до 9 223 372 036 854 775 807 (PHP_INT_MAX). При выходе за пределы число автоматически становится float.
$big = 9223372036854775807;
$bigger = $big + 1;
var_dump($bigger); // float(9.223372036854776E+18)
// Для больших целых используйте библиотеку GMP или BCMath
float(9.223372036854776E+18)
3. Автоматическое приведение типов при арифметических операциях
Если один из операндов float, результат - float. Если оба int - int (если не происходит деление).
echo 10 / 4; // 2.5 (float)
echo 10 % 4; // 2 (int)
echo '10' + 5; // 15 (int, строка преобразована)
echo '10abc' + 5; // 15 (warning: non well formed numeric value)
2.5 2 15 15
4. Использование null и присваивание по умолчанию
Тип null может быть присвоен переменной, которая ранее имела другое значение. Оператор null coalescing (??) появился в PHP 7.
$name = $_GET['name'] ?? 'гость';
// Эквивалент: isset($_GET['name']) ? $_GET['name'] : 'гость'
echo $name;
гость (если параметр отсутствует)
5. Объекты и магия __toString
Класс, реализующий метод __toString(), может быть преобразован к строке автоматически. Без него попытка эха объекта выдаст ошибку.
class User {
public $name = 'Анна';
public function __toString() {
return $this->name;
}
}
$user = new User();
echo $user; // Анна
Анна
6. Строгие типы и передача аргументов по ссылке
При строгой типизации нельзя передать переменную несовместимого типа по ссылке, даже если её можно было бы преобразовать.
declare(strict_types=1);
function increment(int &$x) {
$x++;
}
$val = '5';
increment($val); // TypeError: Argument 1 passed to increment() must be of the type int, string given
Fatal error: Uncaught TypeError: Argument 1 passed to increment() must be of the type int, string given
7. Возвращаемый тип : void и null
Метод, объявленный как void, не может возвращать значение, но может содержать return; без выражения. Если требуется вернуть null, используйте ?int (nullable type).
function logMessage(string $msg): void {
file_put_contents('log.txt', $msg, FILE_APPEND);
}
function findUser(int $id): ?array {
return $id === 1 ? ['name'=>'Alex'] : null;
}
$user = findUser(2);
var_dump($user); // NULL
NULL
8. Тип array и синтаксис деструктуризации с list()
В PHP 7 можно деструктурировать массивы с помощью list() и короткого синтаксиса [] в foreach.
$points = [[1,2], [3,4]];
foreach ($points as [$x, $y]) {
echo "($x,$y) ";
}
// (1,2) (3,4)
(1,2) (3,4)
9. Объявление типа iterable и работа с генераторами
Генератор реализует Traversable, поэтому может быть передан в функцию, ожидающую iterable.
function getNumbers(): Generator {
yield 1;
yield 2;
}
function process(iterable $data) {
foreach ($data as $v) echo $v;
}
process(getNumbers()); // 12
12
10. Класс Closure и тип callable
Анонимные функции являются объектами класса Closure, который является callable.
$greet = function($name) {
echo "Привет, $name!";
};
$greet('Андрей');
var_dump(is_callable($greet)); // bool(true)
Привет, Андрей! bool(true)