- Логический тип
- Предикаты
- Комбинирование операций и функций
- Логические операторы
- Отрицание
- Слабая типизация
Кроме арифметических операций в математике есть операции сравнения, например, 5 > 4
или 1 < 3
. Они есть и в программировании. Допустим, когда мы заходим на сайт, введенные логин и пароль сравниваются с теми, какие есть в базе. Если они есть, нас пускают внутрь — аутентифицируют. В этом уроке разберем операции сравнения.
Языки программирования адаптировали все математические операции сравнения в неизменном виде, кроме операторов равенства и неравенства. В математике для этого используется обычное равно =
, но в программировании такое встречается редко.
Во многих языках символ =
используется, чтобы присвоить переменным значения. Поэтому в PHP сравнивают с помощью ==
.
Список операций сравнения:
<
— меньше<=
— меньше или равно>
— больше>=
— больше или равно==
— равно!=
— не равно
Эти операции применяются не только к числам. Например, с помощью оператора равенства можно сравнить строки: password == text
— это сравнение идентичности строк, которые записаны в разных переменных.
Логический тип
Логическая операция типа 5 > 4
или password == text
— это выражение. Его результат — специальное значение True
(«истина») или False
(«ложь»). Это новый для нас тип данных — bool
:
<?php
$result = 5 > 4;
print_r($result); // => true
print_r('one' != 'one'); // => false
Он содержит всего лишь два этих значения. Наряду со строками (string) и целыми и рациональными числами, булев тип (bool) — это один из примитивных типов данных в PHP.
Предикаты
Попробуем написать простую функцию, которая принимает на вход возраст ребенка и определяет, младенец ли он. Младенцами считаются дети до года.
Любая операция — это выражение, поэтому единственной строчкой функции пишем «вернуть то значение, которое получится в результате сравнения age < 1
». В зависимости от того, какой аргумент пришел, сравнение будет истинным (True
) или ложным (False
), а return
вернет этот результат:
<?php
function isInfant($age)
{
return $age < 1;
}
// Для вывода bool используем var_dump(), а не print_r()
var_dump(isInfant(3)); // => bool(false)
var_dump(isInfant(0.5)); // => bool(true)
Подобные функции называют предикатами. Функции-предикаты отвечают на какой-то вопрос и всегда возвращают либо true
, либо false
.
Предикаты во всех языках принято именовать особым образом для простоты анализа. В PHP предикаты, как правило, начинаются с префикса is
, has
или can
, но не ограничены этими словами. Примеры:
isInfant()
— «младенец ли?»hasChildren()
— «есть ли дети?»isEmpty()
— «пустой ли?»hasErrors()
— «есть ли ошибки?»
Комбинирование операций и функций
Логические операции — это выражения, значит, их можно комбинировать с другими выражениями. Например, мы хотим проверить четность числа — кратность двум. В программировании используют такой подход: проверяют остаток от деления на два:
- если остаток
0
— число четное - если остаток не
0
— число нечетное
Остаток от деления — простая, но важная концепция в арифметике, алгебре, в теории чисел и криптографии. Нужно разделить число на несколько равных групп, и если в конце что-то останется — это остаток от деления.
Делим конфеты поровну между людьми:
- 7 конфет, 2 человека: 2 x 3 + остаток 1 — 7 не кратно 2
- 21 конфету, 3 человека: 3 x 7 + остаток 0 — 21 кратно 3
- 19 конфет, 5 человек: 5 x 3 + остаток 4 — 19 не кратно 5
Оператор %
вычисляет остаток от деления:
7 % 2
→1
21 % 3
→0
19 % 5
→4
С помощью него напишем функцию проверки четности:
<?php
function isEven($number)
{
return $number % 2 === 0;
}
isEven(10); // true
isEven(3); // false
В одном выражении мы скомбинировали логический оператор проверки равенства ===
и арифметический оператор %
. Оператор ===
работает почти так же, как ==
. Чуть позже разберем, чем они отличаются.
Приоритет арифметических операций выше логических. Значит, сначала вычисляется арифметическое выражение $number % 2
, затем результат участвует в логическом сравнении.
Это можно расшифровать так:
«Вычислить остаток от деления числа
$number
на 2 и сравнить, равен ли остаток нулю; затем вернуть результат проверки равенства»*
Логические операторы
Логические выражения могут объединяться друг с другом, создавая все более хитрые проверки.
Хороший пример — проверка пароля. Как вы знаете, некоторые сайты при регистрации хотят пароль от 8 до 20 символов в длину.
В математике мы бы написали 8 <= x <= 20
, где x
— это длина конкретного пароля. Но в PHP такой трюк не пройдет.
Нам придется сделать два отдельных логических выражения и соединить их специальным оператором «И»:
<?php
function hasSpecialChars($str)
{
// Проверяет содержание специальных символов в строке
}
// Функция принимает пароль и проверяет, соответствует ли он условиям
function isCorrectPassword($password)
{
$length = strlen($password);
// Скобки задают приоритет, чтобы показать, что к чему относится
return ($length >= 8 && $length <= 20) && hasSpecialChars($password);
}
isCorrectPassword('qwerty'); // false
isCorrectPassword('qwerty1234'); // true
isCorrectPassword('zxcvbnmasdfghjkqwertyui'); // false
Оператор &&
означает «И» — в математической логике это называют конъюнкцией. Все выражение считается истинным только в том случае, когда истинен каждый операнд — каждое из составных выражений. Иными словами, &&
означает «и то, и другое». Приоритет этого оператора ниже, чем приоритет операторов сравнения, поэтому выражение отрабатывает правильно без скобок.
Кроме &&
, часто используется оператор ||
— «ИЛИ» (дизъюнкция). Он означает «или то, или другое, или оба». Операторы можно комбинировать в любом количестве и любой последовательности, но когда одновременно встречаются &&
и ||
, то приоритет лучше задавать скобками.
Область математики, в которой изучаются логические операторы, называется булевой алгеброй. Ниже увидите таблицы истинности — по ним можно определить, каким будет результат, если применить операторы:
И &&
A | B | A && B |
---|---|---|
TRUE | TRUE | TRUE |
TRUE | FALSE | FALSE |
FALSE | TRUE | FALSE |
FALSE | FALSE | FALSE |
ИЛИ ||
A | B | A ‖ B |
---|---|---|
TRUE | TRUE | TRUE |
TRUE | FALSE | TRUE |
FALSE | TRUE | TRUE |
FALSE | FALSE | FALSE |
Отрицание
Наряду с конъюнкцией (И) и дизъюнкцией (ИЛИ), часто используется операция «отрицание». Отрицание меняет логическое значение на противоположное.
В программировании ему соответствует унарный оператор !
. Если есть функция, проверяющая четность числа, то с помощью отрицания можно выполнить проверку нечетности:
<?php
function isEven($number)
{
return $number % 2 === 0;
}
isEven(10); // true
!isEven(10); // false
// В логике двойное отрицание подобно отсутствию отрицания вообще
!!isEven(10); // true
Мы просто добавили !
слева от вызова функции и получили обратное действие. Отрицание — мощный инструмент, который позволяет лаконично выражать задуманные правила в коде без необходимости писать новые функции.
Слабая типизация
Напомним, что PHP — это язык со слабой типизацией:
- Он знает о существовании разных типов (числа, строки и так далее)
- При этом он относится к их использованию не очень строго, пытаясь преобразовывать информацию, когда это кажется разумным
Особенно много автоматических преобразований происходит при работе с логическими операциями. В PHP есть два простых правила, по которым происходят преобразования:
0
,null
и пустая строка''
приводятся кfalse
, поэтому эти значения называют falsy- Все остальное превращается в
true
Это работает и в другую сторону. И true
, и false
преобразовываются в другие типы данных в зависимости от ситуации:
<?php
print_r(true); // => 1
print_r(false); // => (на экран выводится пустая строка)
print_r(0 || 1); // => 1
Оператор ИЛИ работает только с типом bool, но ему даны числа 1
и 0
:
0
преобразуется вfalse
, а1
преобразуется вtrue
- Результат
false || true
— этоtrue
- Теперь
print_r()
получаетtrue
, но он работает только со строками true
преобразуется в1
- И на экран выводится
1
Здесь важно отметить также отличие операторов ==
и ===
. Оно как раз заключается в преобразовании типов.
Пустая строка и false
— это разные значения, поэтому оператор ===
говорит «Ложь! Они не равны!».
Но оператор ==
преобразует типы. С его точки зрения, пустая строка и false
равны. Это преобразование неявное, поэтому по возможности избегайте операторов ==
и !=
:
<?php
var_dump('' === false); // => false
var_dump('' == false); // => true
Вспомним операцию отрицания. При двойном отрицании !!
итоговое значение равно начальному:
<?php
$answer = true;
var_dump(!$answer); // => false
var_dump(!!$answer); // => true
Здесь также дополнительно происходят преобразования типа. Поэтому результатом двойного отрицания всегда будет bool. Этим приемом пользуются, чтобы поменять тип данных.
В разных языках программирования разные правила преобразований. Некоторые языки вообще не преобразовывают типы сами.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты