Арифметика
Чему вы научитесь:
- считать через
+,-,*,/,%и**и предсказывать тип результата; - менять переменную через
++,+=и.=и отличать$i++от++$i; - сравнивать значения через
==и===и объяснять правило PHP 8 для чисел и строк; - подставлять значение по умолчанию через
??и?:и помнить, чтоandслабее=.

Представьте калькулятор с правилами заведения. Он складывает, вычитает и умножает как в школе, но у некоторых кнопок есть свои оговорки. Кнопка / всегда оставляет дробную часть, а отбрасывает дробь отдельная кнопка intdiv.
Кнопки-знаки вроде + и / в программе называют операторами. Чаще всего оператор стоит между двумя значениями и говорит PHP, что с ними сделать. А intdiv — функция: её вызывают по имени, а числа передают в скобках. В теме о типах вы уже видели оператор / и знаете, что результат деления бывает не целым.
Возьмём задачу из жизни: 17 пирожков раскладывают по коробкам, и в каждую помещается 5. Сколько коробок заполнится целиком и сколько пирожков останется?
<?php
$pies = 17;
echo $pies / 5, "\n"; // 3.4
echo intdiv($pies, 5), "\n"; // 3
echo $pies % 5, "\n"; // 2Давайте разберём программу по строкам:
$pies / 5печатает3.4: обычное деление сохраняет дробную часть.intdiv($pies, 5)делит нацело и возвращает3, иechoпечатает его: столько коробок заполнится целиком.$pies % 5печатает2: эти два пирожка не поместились ни в одну полную коробку.
Четыре действия и степень
Арифметические операторы PHP:
+складывает;-вычитает;*умножает;/делит и сохраняет дробную часть;%даёт остаток от деления;**возводит в степень:2 ** 10— это1024.
Тип результата зависит от значений. Сумма двух int — снова int, а если одно из чисел float, результат тоже float: 2 + 1.0 даёт float(3).
Деление ведёт себя по-своему. 10 / 5 даёт int(2), потому что делится нацело, а 7 / 2 даёт float(3.5). Во многих языках деление целых отбрасывает дробь, а в PHP для этого есть отдельная функция.
Деление нацело и остаток
Функция intdiv
intdiv($a, $b) делит одно целое число на другое и отбрасывает дробную часть. Она не округляет:
intdiv(17, 5)даёт3, и3.4превращается в3;intdiv(19, 5)тоже даёт3, хотя3.8ближе к четырём;- у отрицательных чисел дробь тоже отрезается:
intdiv(-7, 2)даёт-3.
Оператор %
Оператор % даёт остаток — то, что не поместилось в полные коробки. Остаток 0 значит, что число разделилось нацело: 10 % 2 даёт 0, и так проверяют, что число чётное.
Остаток бывает отрицательным: его знак совпадает со знаком делимого, то есть левого числа. Поэтому -7 % 3 даёт -1, а 7 % -3 даёт 1. Здесь картинка с коробками перестаёт работать: минус семь пирожков по коробкам не разложишь, а % с отрицательными числами считает и берёт знак у делимого.
Порядок действий
Когда в выражении несколько операторов, PHP выполняет их по приоритету — заранее заданному порядку, как в школьной математике:
- сначала
**; - затем
*,/и%; - потом
+и-; - последним оператор
., который склеивает две строки в одну.
Скобки меняют этот порядок. Давайте посмотрим, что получится:
echo 2 + 3 * 4, "\n"; // 14
echo (2 + 3) * 4, "\n"; // 20
echo 'Total: ' . 2 + 3, "\n"; // Total: 5
echo 'a' . 1 + 2, "\n"; // a3В третьей строке PHP сначала складывает 2 + 3, а потом приклеивает 5 к строке. В четвёртой то же самое: 1 + 2 даёт 3, и выходит a3. Такой порядок действует с PHP 8, а скобки 'Total: ' . (2 + 3) делают его видным с первого взгляда.
Последний пример любят давать на собеседованиях: он проверяет, знаете ли вы, что в PHP 8 сложение выполняется раньше склейки.
Здесь калькулятор перестаёт быть точной картинкой. В настоящий калькулятор строку не введёшь, а PHP склеивает строки и в '5' + 3 сам превращает '5' в число 5.
Деление на ноль
Делить на ноль нельзя, и PHP не пытается угадать ответ:
$boxes = 0;
echo $pies / $boxes, "\n"; // ✗
echo 'done', "\n";Fatal error: Uncaught DivisionByZeroError: Division by zeroPHP останавливает программу на этой строке: всё, что напечатано раньше, остаётся на экране, а слово done не появится. Так же останавливают программу intdiv($pies, 0) и $pies % 0.
Иногда вместо остановки нужна бесконечность. Для этого есть функция fdiv: fdiv(1, 0) возвращает INF, особое значение типа float.
Частая ошибка
Среднее двух чисел считают без скобок:
$a = 4;
$b = 6;
$average = $a + $b / 2; // ✗
echo $average, "\n"; // 7Деление выполняется раньше сложения, поэтому PHP считает 4 + 3 и печатает 7 вместо 5. Сообщения об ошибке нет, и неверное число уходит дальше в программу. Возьмите сумму в скобки: ($a + $b) / 2 даёт 5.
Главное
/сохраняет дробную часть, аintdivотбрасывает её;10 / 5даётint, а7 / 2—float.%даёт остаток, и его знак совпадает со знаком делимого:-7 % 3— это-1.- Сначала
**, затем*,/и%, потом+и-, последней склейка.; скобки меняют порядок. - Деление на ноль останавливает программу с
DivisionByZeroError, аfdiv(1, 0)возвращаетINF.