Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Логические операции Основы 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
Рекомендуемые программы
профессия
Занимайтесь созданием сайтов, веб-приложений, сервисов и их интеграцией с внутренними бизнес-системами на бекенд-языке PHP
10 месяцев
с нуля
Старт 21 ноября

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»