Перейти к содержимому
Теория · Переменные и типы · урок 3 из 6

Скалярные типы

В прошлом уроке в банки клали числа и строки. Теперь посмотрим, чем одни значения отличаются от других.

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

PHP
<?php

$x = 12 / 4;
var_dump($x); // int(3)
$x = 9 / 2;
var_dump($x); // float(4.5)
$x = 'nine';
var_dump($x); // string(4) "nine"

Давайте разберём по строкам:

  1. 12 / 4 делится нацело, и в $x попадает целое число 3.
  2. var_dump($x) печатает тип и значение: int(3).
  3. 9 / 2 нацело не делится, и в $x попадает дробное 4.5 — наклейка сменилась на float.
  4. $x = 'nine' кладёт в ту же переменную строку, и var_dump печатает string(4) "nine".

Когда оба числа целые, оператор / возвращает целое число, если деление получается нацело, и дробное — если остаётся дробная часть. Поэтому одна и та же операция дала два разных типа.

Наклейка здесь — упрощение. PHP хранит тип вместе с самим значением, а не на банке. Поэтому при $b = $a тип переезжает в $b вместе с копией значения.

Четыре скалярных типа и null

Скалярный тип — это вид простого значения: число, строка или ответ «да» или «нет». Таких типов в PHP четыре, и к ним добавляется особый тип null.

int

Целые числа без дробной части: 42, -7, 0. Ими записывают количество штук, номера заказов и возраст.

float

Дробные числа: 3.5, -0.25. Такое число называют числом с плавающей точкой. Дробную часть в коде отделяет точка, а не запятая. Число 2.0 — тоже float, хотя дробная часть у него нулевая.

string

Текст в кавычках: 'Anna', '42'. Строка '42' — это текст из двух символов, а не число.

bool

Логическое значение: true или false, «да» или «нет». Оно отвечает на вопросы вроде «оплачен ли заказ».

null

Единственное значение null означает «в банке ничего нет». Переменная со значением null при этом существует: в отличие от переменной, которой ничего не присваивали, её читают без предупреждения.

Как читать var_dump

Функция var_dump печатает тип и значение, каждое значение — на отдельной строке:

PHP
var_dump(42); // int(42)
var_dump(2.0); // float(2)
var_dump('abcd'); // string(4) "abcd"
var_dump(false); // bool(false)
var_dump(null); // NULL

Что означает каждая строка вывода:

  • int(42) — целое число 42;
  • float(2) — дробное число: var_dump не печатает нулевую дробную часть, но тип называет;
  • string(4) "abcd" — строка: в скобках её длина, в кавычках сама строка;
  • bool(false) — логическое значение;
  • NULL — значение null, без скобок.

В var_dump можно передать несколько значений через запятую. Каждое из них он напечатает на своей строке, в том же формате.

Есть и функция gettype, которая возвращает название типа строкой. Но названия у неё старые: gettype(3.5) даёт 'double', а gettype(42) — 'integer'. Поэтому тип в курсе показываем через var_dump.

Дробные числа неточны

Число с плавающей точкой хранится в двоичном виде, и 0.1 в нём записать точно нельзя. Так же и в десятичной записи нельзя точно записать одну треть: 0.333… где-то приходится обрезать.

PHP
var_dump(0.1 + 0.2); // float(0.30000000000000004)
echo 0.1 + 0.2, "\n"; // 0.3

var_dump показывает число полностью, и видно, что сумма чуть больше 0.3. echo печатает дробное число с точностью до 14 значащих цифр и округляет его до 0.3, поэтому ошибку не видно.

Это классический вопрос на собеседовании: «Почему 0.1 + 0.2 не равно 0.3?» Ответ: float хранит двоичное приближение, а не точное десятичное число. Поэтому деньги считают в копейках и хранят как int.

Частая ошибка

Дробную часть отделили запятой, как принято в русском тексте:

PHP
$price = 3,5; // ✗
TEXT
Parse error: syntax error, unexpected token ","

Это ошибка разбора: PHP не понимает, что делает запятая после 3, и не запускает файл вовсе. В коде дробную часть всегда отделяет точка: $price = 3.5;.

Главное

  • Тип есть у значения, а не у переменной: новое значение приносит свой тип.
  • Скалярных типов четыре: int, float, string, bool. Есть ещё особый тип null.
  • var_dump печатает тип и значение: int(3), float(4.5), string(4) "abcd", bool(true), NULL.
  • / с двумя int даёт int, когда они делятся нацело, иначе float; 0.1 + 0.2 — не ровно 0.3.