Зарегистрируйтесь, чтобы продолжить обучение

Логические операции Основы PHP

even-or-odd

Кроме арифметических операций в математике есть операции сравнения, например, 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 % 21
  • 21 % 30
  • 19 % 54

С помощью него напишем функцию проверки четности:

<?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:

  1. 0 преобразуется в false, а 1 преобразуется в true
  2. Результат false || true — это true
  3. Теперь print_r() получает true, но он работает только со строками
  4. true преобразуется в 1
  5. И на экран выводится 1

Здесь важно отметить также отличие операторов == и ===. Оно как раз заключается в преобразовании типов.

Пустая строка и false — это разные значения, поэтому оператор === говорит «Ложь! Они не равны!».

Но оператор == преобразует типы. С его точки зрения, пустая строка и false равны. Это преобразование неявное, поэтому по возможности избегайте операторов == и !=:

<?php

var_dump('' === false); // => false
var_dump('' == false);  // => true

Вспомним операцию отрицания. При двойном отрицании !! итоговое значение равно начальному:

<?php

$answer = true;
var_dump(!$answer);  // => false
var_dump(!!$answer); // => true

Здесь также дополнительно происходят преобразования типа. Поэтому результатом двойного отрицания всегда будет bool. Этим приемом пользуются, чтобы поменять тип данных.

В разных языках программирования разные правила преобразований. Некоторые языки вообще не преобразовывают типы сами.


Дополнительные материалы

  1. Булева алгебра
  2. Законы Де Моргана
  3. Booleans

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff