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

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

Кроме арифметических операций со школы нам известны операции сравнения. Например, 5 > 4. Это звучит как вопрос: «5 больше 4?». В данном случае ответ «да». В других случаях ответом может быть «нет» (например, для 3 < 1).

Операции сравнения не имеют привязки к числам. Сравнивать можно практически всё, что угодно, например, строки. Каждый раз, когда мы входим на какой-то сайт, внутри происходит сравнение введенных логина и пароля с теми, какие есть в базе. И только если они есть, нас пускают во внутрь (аутентифицируют).

Языки программирования адаптировали все математические операции сравнения практически в неизменном виде. Единственное серьезное отличие – операторы равенства и неравенства. В математике для этого используется обычное равно =, но в программировании такое встречается не часто. Во многих языках символ = используется для присваивания значений переменным, поэтому для сравнения взяли == или ===.

Список операций сравнения:

  • < меньше
  • <= меньше или равно
  • > больше
  • >= больше или равно
  • === равно
  • !== не равно

Для равенства и неравенства также существуют операторы == и !=, которые мы не будем использовать из-за потенциальной опасности. Мы поговорим об этом ниже.

Логическая операция типа 5 > 4 или $password === $text — это выражение, и его результат — специальное значение true («истина») или false («ложь»). Это новый для нас тип данных — bool. Он содержит всего лишь два этих значения. Наряду со строками (string) и целыми и рациональными числами, тип bool (булев) — это один из примитивных типов данных в PHP.

<?php

$result = 5 > 4;
print_r($result); // => true
print_r('one' !== 'one'); // => false

Предикаты

Напишем примитивную функцию, которая принимает на вход возраст ребенка и определяет, младенец ли он. Младенцами считаются дети до года:

Пользуемся тем фактом, что любая операция — это выражение, поэтому единственной строчкой функции пишем «вернуть то значение, которое получится в результате сравнения $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() — «есть ли ошибки?»

Комбинирование операций и функций

Логические операции — это выражения. Значит, логические операции можно комбинировать с другими выражениями. Например, мы хотим проверить чётность числа, то есть кратность двум. В программировании используют такой подход:

  • проверяют остаток от деления на 2:
    • если остаток 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, но он работает только со строками (не с bool).
  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. Этим приёмом пользуются, чтобы поменять тип данных.

В разных языках программирования разные правила преобразований. Некоторые языки вообще не преобразовывают типы сами. Многие особенности PHP откровенно не самые удачные, но это историческое наследие языка. Если бы его создавали сегодня с нуля, то многие правила и нюансы наверняка были бы совсем иными.


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

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

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.

Об обучении на Хекслете

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

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

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

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

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы PHP-разработчик
Профессия
Разработка веб-приложений на Laravel
25 мая 10 месяцев

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

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

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

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Изображение Тото

Задавайте вопросы, если хотите обсудить теорию или упражнения. Команда поддержки Хекслета и опытные участники сообщества помогут найти ответы и решить задачу