Логические операции — Основы PHP
Языки программирования адаптировали все математические операции сравнения в неизменном виде, кроме операторов равенства и неравенства. В математике для этого используется обычное равно = , но в программировании такое встречается редко.
Во многих языках символ = используется, чтобы присвоить переменным значения. Поэтому в PHP сравнивают с помощью == .
Список операций сравнения:
Эти операции применяются не только к числам. Например, с помощью оператора равенства можно сравнить строки: password == text — это сравнение идентичности строк, которые записаны в разных переменных.
Логический тип
Логическая операция типа 5 > 4 или password == text — это выражение. Его результат — специальное значение True («истина») или False («ложь»). Это новый для нас тип данных — bool :
$result = 5 > 4; print_r($result); // => true print_r('one' !== 'one'); // => false
Он содержит всего лишь два этих значения. Наряду со строками (string) и целыми и рациональными числами, булев тип (bool) — это один из примитивных типов данных в PHP.
Предикаты
Попробуем написать простую функцию, которая принимает на вход возраст ребенка и определяет, младенец ли он. Младенцами считаются дети до года.
Любая операция — это выражение, поэтому единственной строчкой функции пишем «вернуть то значение, которое получится в результате сравнения age < 1 ». В зависимости от того, какой аргумент пришел, сравнение будет истинным ( True ) или ложным ( False ), а return вернет этот результат:
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() — «есть ли ошибки?»
Комбинирование операций и функций
Логические операции — это выражения, значит, их можно комбинировать с другими выражениями. Например, мы хотим проверить четность числа — кратность двум. В программировании используют такой подход: проверяют остаток от деления на два:
Остаток от деления — простая, но важная концепция в арифметике, алгебре, в теории чисел и криптографии. Нужно разделить число на несколько равных групп, и если в конце что-то останется — это остаток от деления.
Делим конфеты поровну между людьми:
- 7 конфет, 2 человека: 2 x 3 + остаток 1 — 7 не кратно 2
- 21 конфету, 3 человека: 3 x 7 + остаток 0 — 21 кратно 3
- 19 конфет, 5 человек: 5 x 3 + остаток 4 — 19 не кратно 5
Оператор % вычисляет остаток от деления:
С помощью него напишем функцию проверки четности:
function isEven($number) return $number % 2 === 0; > isEven(10); // true isEven(3); // false
В одном выражении мы скомбинировали логический оператор проверки равенства === и арифметический оператор % .
Приоритет арифметических операций выше логических. Значит, сначала вычисляется арифметическое выражение $number % 2 , затем результат участвует в логическом сравнении.
Это можно расшифровать так:
«Вычислить остаток от деления числа $number на 2 и сравнить, равен ли остаток нулю; затем вернуть результат проверки равенства»*
Логические операторы
Логические выражения могут объединяться друг с другом, создавая все более хитрые проверки.
Хороший пример — проверка пароля. Как вы знаете, некоторые сайты при регистрации хотят пароль от 8 до 20 символов в длину.
Нам придется сделать два отдельных логических выражения и соединить их специальным оператором «И»:
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 | TRUE |
FALSE | TRUE | TRUE |
FALSE | FALSE | FALSE |
Отрицание
Наряду с конъюнкцией (И) и дизъюнкцией (ИЛИ), часто используется операция «отрицание». Отрицание меняет логическое значение на противоположное.
В программировании ему соответствует унарный оператор ! . Если есть функция, проверяющая четность числа, то с помощью отрицания можно выполнить проверку нечетности:
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 преобразовываются в другие типы данных в зависимости от ситуации:
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 равны. Это преобразование неявное, поэтому по возможности избегайте операторов == и != :
var_dump('' === false); // => false var_dump('' == false); // => true
Вспомним операцию отрицания. При двойном отрицании !! итоговое значение равно начальному:
$answer = true; var_dump(!$answer); // => false var_dump(!!$answer); // => true
Здесь также дополнительно происходят преобразования типа. Поэтому результатом двойного отрицания всегда будет bool. Этим приемом пользуются, чтобы поменять тип данных.
В разных языках программирования разные правила преобразований. Некоторые языки вообще не преобразовывают типы сами.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Об обучении на Хекслете
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Логические операторы в PHP
Логические операторы позволяют указывать сразу несколько условий для одного блока IF:
Оператор && , который ещё называется логическое И, приводит значения слева и справа к булеву типу, а затем и сам возвращает булево значение: true если слева и справа true , либо false если одно из условий false .
Другими словами, если и одно, и другое условие истинно, то и оператор && возвращает истину. Что и отражает название оператора.
Оператор || или логическое ИЛИ возвращает истину когда истинно хотя бы одно из двух условий:
5 || 1 > 2) echo 'Условие выполнено.'; ?>
В коде выше команда echo будет выполнена, поскольку одно из условий истинно.
Все логические операторы в PHP
$a && $b | Истина, если $a и $b равны true. |
$a || $b | Истина, если хотя бы одна из $a и $b равна true. |
$a xor $b | Истина, если одна из $a и $b равна true, но не обе. |
!$a | Истина, если $a не равна true. |
$a and $b | Аналогично && |
$a or $b | Аналогично || |
Между операторами && и and , а также между || и or есть небольшое различие — порядок выполнения.
Как вы знаете, умножение имеет больший приоритет, чем сложение. Так вот, операторы and и or имеют приоритет ниже, чем оператор присваивания = . Результат можно увидеть в следующем примере:
Поскольку у = приоритет выше, PHP воспримет код так:
Т.е. сначала он присваивает переменной $var значение true , а затем происходит операция true and false , которая не имеет смысла, поскольку не влияет на значение переменной.
Ниже расположена таблица с приоритетами операторов. С некоторыми из них вы уже встречались. Чем выше оператор в таблице — тем выше его приоритет.
- ++ — ~ (int) (float) (string) (array) (object) (bool) @
- * / %
- + — .
- < >=
- == != === !== <>
- &&
- ||
- ? : (тернарный оператор)
- = += -= *= **= /= .= %= &= |= ^= <>=
- and
- xor
- or
Теперь мы можем определить, что приоритет операторов сравнения (==, != и т.д.) выше, чем у логических операторов. Эта информация пригодится нам для выполнения задачи.
Задача
Каким будет результат выполнения следующего выражения?