Логические выражения могут объединяться друг с другом, создавая все более хитрые проверки.
Хороший пример — проверка пароля. Как вы знаете, некоторые сайты при регистрации хотят пароль от 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 |
Реализуйте функцию isLeapYear()
, которая определяет, является ли год високосным или нет. Год будет високосным, если он кратен (то есть делится без остатка) 400 или он одновременно кратен 4 и не кратен 100. Как видите, в определении уже заложена вся необходимая логика, осталось только переложить её на код:
<?php
isLeapYear(2018); // false
isLeapYear(2017); // false
isLeapYear(2016); // true
Кратность можно проверять так:
<?php
// % - возвращает остаток от деления левого операнда на правый
// Проверяем что number кратен 10
$number % 10 === 0
// Проверяем что number не кратен 10
$number % 10 !== 0
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Ваше упражнение проверяется по этим тестам
1<?php
2
3namespace HexletBasics\Logic\LogicalOperators;
4
5use PHPUnit\Framework\TestCase;
6
7class Test extends TestCase
8{
9 public function test()
10 {
11 require 'index.php';
12
13 assert(isLeapYear(2016));
14 assert(isLeapYear(2000));
15 assert(!isLeapYear(2017));
16 assert(!isLeapYear(2018));
17 assert(!isLeapYear(1900));
18 }
19}
20
Решение учителя откроется через: