4. Типы данных
Введение
Заголовок раздела «Введение»PHP — динамически типизированный язык, что означает, что тип переменной определяется автоматически в зависимости от присвоенного значения. Однако понимание типов данных критически важно для написания корректного и безопасного кода.
Что вы узнаете
Заголовок раздела «Что вы узнаете»- Скалярные типы (string, integer, float, boolean)
- Составные типы (array, object)
- Специальные типы (resource, NULL)
- Проверка и преобразование типов
- Строгая типизация (PHP 7+)
- Type hinting и return types
Скалярные типы
Заголовок раздела «Скалярные типы»Скалярные типы хранят одно значение.
String (строка)
Заголовок раздела «String (строка)»Строка — последовательность символов.
<?php// Двойные кавычки (обрабатываются переменные и escape-последовательности)$greeting = "Привет, мир!";$name = "Алексей";$message = "Привет, $name!"; // Интерполяция
// Одинарные кавычки (литеральная строка)$text = 'Это просто текст';$literal = 'Переменная $name не обработается';
// Heredoc (для многострочных строк с интерполяцией)$html = <<<HTML<div class="user"> <h2>$name</h2> <p>Добро пожаловать!</p></div>HTML;
// Nowdoc (без интерполяции, как одинарные кавычки)$config = <<<'CONFIG'server=localhostport=3306user=$dbUserCONFIG;
echo $message;?>```text
#### Escape-последовательности
```php<?php// Работают только в двойных кавычках$text = "Строка1\nСтрока2"; // \n - новая строка$tab = "Колонка1\tКолонка2"; // \t - табуляция$quote = "Он сказал: \"Привет!\""; // \" - экранирование кавычек$backslash = "Путь: C:\\xampp\\htdocs"; // \\ - обратный слеш
echo nl2br($text); // Конвертирует \n в <br>?>```text
#### Полезные функции для строк
```php<?php$str = " Hello, World! ";
// Длина строкиecho strlen($str); // 17
// Убрать пробелыecho trim($str); // "Hello, World!"
// Верхний/нижний регистрecho strtoupper($str); // " HELLO, WORLD! "echo strtolower($str); // " hello, world! "
// Заменаecho str_replace("World", "PHP", $str); // " Hello, PHP! "
// Поиск подстрокиif (strpos($str, "Hello") !== false) { echo "Найдено!";}
// Разбить строку на массив$parts = explode(", ", "apple, banana, orange");print_r($parts); // ["apple", "banana", "orange"]
// Объединить массив в строку$fruits = ["apple", "banana", "orange"];echo implode(", ", $fruits); // "apple, banana, orange"?>```text
### Integer (целое число)
Целые числа без дробной части.
```php<?php$decimal = 42; // Десятичное$negative = -15; // Отрицательное$octal = 0755; // Восьмеричное (начинается с 0)$hex = 0xFF; // Шестнадцатеричное (начинается с 0x)$binary = 0b1010; // Двоичное (начинается с 0b)
// PHP_INT_MAX - максимальное значениеecho PHP_INT_MAX; // 9223372036854775807 (64-bit)
// Проверка типаvar_dump(is_int($decimal)); // bool(true)var_dump(is_int(42.5)); // bool(false)?>```text
#### Операции с целыми числами
```php<?php$a = 10;$b = 3;
echo $a + $b; // 13 (сложение)echo $a - $b; // 7 (вычитание)echo $a * $b; // 30 (умножение)echo $a / $b; // 3.333... (деление)echo $a % $b; // 1 (остаток от деления)echo $a ** $b; // 1000 (возведение в степень, PHP 5.6+)
// Целочисленное делениеecho intdiv($a, $b); // 3 (PHP 7+)?>```text
### Float (число с плавающей точкой)
Числа с дробной частью (также называются double).
```php<?php$price = 99.99;$pi = 3.14159;$scientific = 1.5e3; // 1500 (научная нотация)$negative = -0.001;
// Проверка типаvar_dump(is_float($price)); // bool(true)
// Форматированиеecho number_format($price, 2); // "99.99"echo number_format(1234567.89, 2, ',', ' '); // "1 234 567,89"
// Округлениеecho round(3.4); // 3echo round(3.5); // 4echo ceil(3.1); // 4 (округление вверх)echo floor(3.9); // 3 (округление вниз)?>```text
#### Осторожно с float!
```php<?php// ⚠️ Проблема точности с плавающей точкой$a = 0.1;$b = 0.2;$sum = $a + $b;
var_dump($sum); // float(0.30000000000000004)
// ❌ Неправильно: сравнение float напрямуюif ($sum == 0.3) { echo "Равно"; // Может не сработать!}
// ✅ Правильно: сравнение с точностью$epsilon = 0.00001;if (abs($sum - 0.3) < $epsilon) { echo "Равно"; // Работает}
// ✅ Для денег используйте integer (копейки)$price_cents = 9999; // 99.99 руб$display_price = $price_cents / 100;?>```text
### Boolean (булев тип)
Логические значения: `true` или `false`.
```php<?php$is_active = true;$is_deleted = false;
// Проверкаvar_dump(is_bool($is_active)); // bool(true)
// Преобразование в booleanvar_dump((bool)""); // bool(false) - пустая строкаvar_dump((bool)"0"); // bool(false) - строка "0"var_dump((bool)"false"); // bool(true) - непустая строка!var_dump((bool)0); // bool(false) - нольvar_dump((bool)1); // bool(true)var_dump((bool)-1); // bool(true) - любое не-нольvar_dump((bool)[]); // bool(false) - пустой массивvar_dump((bool)[1]); // bool(true)var_dump((bool)null); // bool(false)?>```text
#### Falsy values (ложные значения)
Следующие значения считаются `false`:
```php<?php// Все эти значения == false$falsy_values = [ false, 0, 0.0, "0", "", null, [] // пустой массив];
foreach ($falsy_values as $val) { if (!$val) { echo "Это falsy значение\n"; }}?>```text
## Составные типы
### Array (массив)
Массивы хранят множество значений.
```php<?php// Индексированный массив (numeric array)$fruits = ["apple", "banana", "orange"];$fruits = array("apple", "banana", "orange"); // Старый синтаксис
echo $fruits[0]; // "apple"echo $fruits[1]; // "banana"
// Ассоциативный массив (associative array)$user = [ "name" => "Иван", "age" => 25];
echo $user["name"]; // "Иван"
// Многомерный массив$users = [ [ "name" => "Иван", "age" => 25 ], [ "name" => "Мария", "age" => 30 ]];
echo $users[0]["name"]; // "Иван"echo $users[1]["age"]; // 30?>```text
#### Операции с массивами
```php<?php$arr = ["a", "b", "c"];
// Добавление элементов$arr[] = "d"; // В конецarray_push($arr, "e", "f"); // В конец (несколько)array_unshift($arr, "z"); // В начало
// Удаление элементовarray_pop($arr); // Удалить последнийarray_shift($arr); // Удалить первыйunset($arr[2]); // Удалить по индексу
// Подсчет элементовecho count($arr);
// Проверка существованияif (in_array("b", $arr)) { echo "Найдено!";}
if (isset($arr[5])) { echo "Индекс 5 существует";}
// Слияние массивов$arr1 = [1, 2, 3];$arr2 = [4, 5, 6];$merged = array_merge($arr1, $arr2); // [1, 2, 3, 4, 5, 6]?>```text
Подробнее о массивах мы поговорим в отдельном уроке.
### Object (объект)
Объекты — экземпляры классов.
```php<?phpclass User { public $name; public $email;
public function __construct($name, $email) { $this->name = $name; $this->email = $email; }
public function greet() { return "Привет, меня зовут " . $this->name; }}
// Создание объекта
echo $user->name; // "Алексей"echo $user->greet(); // "Привет, меня зовут Алексей"
// Проверка типаvar_dump(is_object($user)); // bool(true)?>```text
Объекты и ООП мы подробно разберем в разделе про классы.
## Специальные типы
### NULL
NULL представляет отсутствие значения.
```php<?php$var = null;
// Переменная становится NULL в трех случаях:// 1. Явное присваивание$a = null;
// 2. Переменная объявлена, но не инициализирована// $b; // null (но вызовет Notice)
// 3. Переменная удалена$c = 123;unset($c); // Теперь $c = null
// Проверка на NULLvar_dump(is_null($var)); // bool(true)var_dump($var === null); // bool(true)var_dump(isset($var)); // bool(false)
// Оператор объединения с null (PHP 7+)$username = $_GET['user'] ?? 'Гость';// Если $_GET['user'] не существует или null, вернет 'Гость'?>```text
### Resource (ресурс)
Ресурс — специальная переменная, ссылающаяся на внешний ресурс (файл, БД, изображение).
```php<?php// Открытие файла$file = fopen("data.txt", "r");var_dump(is_resource($file)); // bool(true)fclose($file);
// Подключение к БД$connection = mysqli_connect("localhost", "user", "password", "database");var_dump(is_resource($connection)); // bool(true)mysqli_close($connection);
// Работа с изображениями (GD)$image = imagecreate(200, 100);var_dump(is_resource($image)); // bool(true)imagedestroy($image);?>```text
## Проверка типов
PHP предоставляет функции для проверки типов:
```php<?php$var = "Hello";
// Проверка конкретного типаis_string($var); // trueis_int($var); // falseis_float($var); // falseis_bool($var); // falseis_array($var); // falseis_object($var); // falseis_null($var); // falseis_resource($var); // false
// Универсальная проверка типаecho gettype($var); // "string"
// Проверка на скалярный типis_scalar($var); // true (string, int, float, bool)
// Проверка на числовой типis_numeric("123"); // trueis_numeric("12.5"); // trueis_numeric("abc"); // false?>```text
### Функция var_dump() для отладки
```php<?php$data = [ "name" => "Иван", "age" => 25, "active" => true, "balance" => 99.99, "address" => null];
var_dump($data);// array(5) {// ["name"]=>// string(8) "Иван"// ["age"]=>// int(25)// ["active"]=>// bool(true)// ["balance"]=>// float(99.99)// ["address"]=>// NULL// }?>```text
## Преобразование типов
### Автоматическое преобразование (type juggling)
PHP автоматически преобразует типы:
```php<?php// Строка + число$result = "5" + 10;var_dump($result); // int(15)
// Строка * число$result = "3" * "4";var_dump($result); // int(12)
// Конкатенация преобразует в строку$result = 10 . 20;var_dump($result); // string(4) "1020"
// Логические операции$result = "5" > 3;var_dump($result); // bool(true)
// ⚠️ Осторожно с нечисловыми строками$result = "hello" + 5;var_dump($result); // int(5) - "hello" стало 0!?>```text
### Явное преобразование (type casting)
```php<?php$value = "123.45";
// Приведение типов$int = (int)$value; // 123$float = (float)$value; // 123.45$string = (string)$value; // "123.45"$bool = (bool)$value; // true
// Альтернативные функции$int = intval($value); // 123$float = floatval($value); // 123.45$string = strval($value); // "123.45"
var_dump($int, $float, $string, $bool);?>```text
### Преобразование в массив и объект
```php<?php// В массив$string = "hello";$array = (array)$string;var_dump($array); // array(1) { [0]=> string(5) "hello" }
// Объект в массив$obj = (object)["name" => "Иван", "age" => 25];$array = (array)$obj;var_dump($array);
// Массив в объект$obj = (object)$array;echo $obj->name; // "Мария"?>```text
## Строгая типизация (PHP 7+)
С PHP 7 можно включить строгую типизацию.
### Без строгой типизации (по умолчанию)
```php<?phpfunction add(int $a, int $b) { return $a + $b;}
// PHP автоматически преобразует строки в intecho add("5", "10"); // 15 (работает)echo add("5.7", 3); // 8 (преобразует 5.7 в 5)?>```text
### Со строгой типизацией
```php<?phpdeclare(strict_types=1); // Включаем строгую типизацию
function add(int $a, int $b): int { return $a + $b;}
echo add(5, 10); // 15 (работает)echo add("5", "10"); // TypeError: Argument must be of type int, string given?>```text
### Type hints и return types
```php<?phpdeclare(strict_types=1);
// Type hints для параметров и return typefunction getUserName(int $user_id): string { // Всегда должен вернуть string return "User_" . $user_id;}
// Nullable types (PHP 7.1+)function findUser(?int $id): ?string { // Может принять int или null // Может вернуть string или null if ($id === null) { return null; } return "User_" . $id;}
// Union types (PHP 8.0+)function process(int|float $number): int|float { // Принимает int ИЛИ float // Возвращает int ИЛИ float return $number * 2;}
// Mixed type (любой тип, PHP 8.0+)function handleData(mixed $data): mixed { return $data;}
echo getUserName(42); // "User_42"echo findUser(null); // nullecho process(5); // 10echo process(3.5); // 7.0?>```text
## WordPress контекст
В WordPress важно правильно работать с типами данных для безопасности.
### Sanitization (очистка) данных
```php<?php// Получаем данные из формы$post_title = $_POST['title']; // ❌ ОПАСНО
// ✅ Правильно: очистка и валидация$post_title = sanitize_text_field($_POST['title']);$post_content = wp_kses_post($_POST['content']);$user_id = absint($_POST['user_id']); // Приведение к положительному int$email = sanitize_email($_POST['email']);$url = esc_url($_POST['website']);
// Создание постаwp_insert_post([ 'post_title' => $post_title, 'post_content' => $post_content, 'post_author' => $user_id, 'post_status' => 'publish']);?>```text
### Escape вывод
```php<?php// Получаем данные$user_input = get_post_meta(get_the_ID(), 'custom_field', true);
// ❌ ОПАСНО: XSS атакаecho $user_input;
// ✅ Правильно: экранированиеecho esc_html($user_input); // Обычный текстecho esc_attr($user_input); // Атрибуты HTMLecho esc_url($user_input); // URLecho esc_js($user_input); // JavaScriptecho wp_kses_post($user_input); // HTML с разрешенными тегами?>```text
### Type hinting в WordPress
```php<?php/** * Получить посты определенного типа * * @param string $post_type Тип поста * @param int $number Количество постов * @return array Массив постов */function get_custom_posts(string $post_type, int $number = 10): array { $args = [ 'post_type' => $post_type, 'posts_per_page' => $number, 'post_status' => 'publish' ];
$query = new WP_Query($args);
return $query->posts;}
// Использование$posts = get_custom_posts('post', 5);?>```text
## Практика
### Задание 1: Определение типов
Создайте переменные разных типов и выведите их тип с помощью `gettype()` и `var_dump()`.
```php<?php$string = "Hello";$integer = 42;$float = 3.14;$boolean = true;$array = [1, 2, 3];$null = null;
echo gettype($string) . "<br>";echo gettype($integer) . "<br>";// ... и так далее
var_dump($string);var_dump($integer);// ... и так далее?>```text
### Задание 2: Преобразование типов
Создайте строку `"123.45"` и преобразуйте её во все возможные типы, выведите результаты.
### Задание 3: Калькулятор с типами
Создайте функцию калькулятора с type hints:
```php<?phpdeclare(strict_types=1);
function calculate(float $a, float $b, string $operation): float { switch ($operation) { case '+': return $a + $b; case '-': return $a - $b; case '*': return $a * $b; case '/': return $b != 0 ? $a / $b : 0; default: return 0; }}
echo calculate(10, 5, '+'); // 15echo calculate(10, 5, '*'); // 50?>```text
### Задание 4: Проверка типов
Создайте функцию, которая принимает переменную и выводит её тип и значение.
### Задание 5: Работа с null
Используйте оператор `??` для работы с потенциально отсутствующими значениями.
```php<?php$username = $_GET['user'] ?? 'Гость';$page = $_GET['page'] ?? 1;$items_per_page = $_GET['limit'] ?? 10;
echo "Пользователь: $username<br>";echo "Страница: $page<br>";echo "На странице: $items_per_page<br>";?>```text
## Онлайн-редакторы
Протестируйте примеры:- **PHPSandbox**: https://phpsandbox.io/- **3v4l**: https://3v4l.org/ (проверьте поведение на разных версиях PHP!)
## Итоги
В этом уроке вы изучили:
✅ **Скалярные типы** — string, integer, float, boolean✅ **Составные типы** — array, object✅ **Специальные типы** — NULL, resource✅ **Проверку типов** — is_*, gettype(), var_dump()✅ **Преобразование типов** — автоматическое и явное✅ **Строгую типизацию** — declare(strict_types=1)✅ **Type hints и return types** — современный PHP
### Следующий шаг
Теперь изучим операторы для работы с этими типами: [Операторы](/php/operators/)
### Ключевые моменты
1. **PHP динамически типизирован** — тип определяется автоматически2. **Строгая типизация рекомендуется** — меньше ошибок3. **Осторожно с float** — проблемы с точностью4. **NULL !== 0 !== ""** — разные falsy значения5. **В WordPress всегда очищайте данные** — безопасность превыше всего
**Совет:** Используйте `var_dump()` для отладки — это ваш лучший инструмент понимания типов!
---
**Готовы двигаться дальше?** Переходите к следующему уроку: [Операторы](/php/operators/)