and
Оператор and в PHP — отличия от &&, приоритет операторов, короткое замыкание и ловушка с присваиванием. Примеры использования.
Оператор and в PHP
В PHP есть два логических оператора И: && и and. Оба возвращают true только тогда, когда оба операнда принимают значение true, и false в противном случае. Разница заключается в приоритете операторов: && имеет значительно более высокий приоритет, чем and. Именно это единственное отличие является причиной почти каждой ошибки, связанной с and, поэтому данная страница подробно рассматривает данный вопрос.
В этом руководстве объясняется синтаксис and, принцип работы короткого замыкания, почему важен приоритет операторов и классическая ловушка с присваиванием, которой следует избегать.
Синтаксис
Оператор and объединяет два условия в одно boolean-выражение. Чаще всего он используется внутри оператора if для проверки нескольких условий одновременно:
<?php
if (condition1 and condition2) {
// Runs only if BOTH conditions are true
}Тело выполняется только тогда, когда оба операнда истинны. Выражение condition1 and condition2 само по себе вычисляется как boolean (true или false), поэтому результат можно сохранить в переменной — но остерегайтесь ловушки с присваиванием, описанной ниже.
Поведение and
$a | $b | $a and $b |
|---|---|---|
true | true | true |
true | false | false |
false | true | false |
false | false | false |
PHP вычисляет and слева направо с коротким замыканием: если левый операнд ложный, правый операнд никогда не вычисляется, поскольку результат уже не может быть true. Это полезно для защиты дорогостоящей или небезопасной проверки за счёт дешёвой:
<?php
$user = null;
// isLoggedIn() is never called because $user is null,
// so we avoid a "method on null" error.
if ($user !== null and $user->isLoggedIn()) {
echo "Welcome back." . PHP_EOL;
} else {
echo "Please log in." . PHP_EOL;
}
// Output: Please log in.Примеры
<?php
// Example 1
$age = 25;
$hasID = true;
if ($age >= 18 and $hasID) {
echo "You may enter the club." . PHP_EOL;
}
// Output: You may enter the club.
// Example 2
$username = "admin";
$password = "password123";
if ($username == "admin" and $password == "password123") {
echo "Access granted." . PHP_EOL;
}
// Output: Access granted.
// Example 3
$isWeekday = true;
$time = "12:30";
if ($isWeekday and $time >= "09:00" and $time <= "17:00") {
echo "The office is open." . PHP_EOL;
}
// Output: The office is open.Каждый if объединяет несколько условий с помощью and, и тело выполняется только тогда, когда все они истинны.
Приоритет: and vs &&
and имеет очень низкий приоритет — ниже, чем у ||, ниже, чем у =, и ниже, чем у or (and имеет более высокий приоритет, чем or, но оба находятся в нижней части таблицы приоритетов). Оператор &&, напротив, стоит высоко — сразу ниже операторов сравнения. Поэтому при смешении логических операторов с арифметическими, присваиванием или or часто требуются скобки.
Когда and и or встречаются вместе, and вычисляется первым:
<?php
$age = 16;
$hasID = false;
$isStudent = true;
// Reads as: ($age >= 18 and $hasID) or $isStudent
if ($age >= 18 and $hasID or $isStudent) {
echo "Access granted." . PHP_EOL;
}
// Output: Access granted.Добавьте скобки, чтобы явно указать группировку или изменить её:
<?php
$age = 16;
$hasID = false;
$isStudent = true;
// Force the OR to be checked first
if ($age >= 18 and ($hasID or $isStudent)) {
echo "Access granted." . PHP_EOL;
} else {
echo "Access denied." . PHP_EOL;
}
// Output: Access denied.Ловушка с присваиванием
Это та самая ловушка, из-за которой большинство разработчиков предпочитают &&. Поскольку and имеет более низкий приоритет, чем =, присваивание происходит до выполнения and:
<?php
$a = true;
$b = false;
// Parsed as: ($result = $a) and $b
$result = $a and $b;
var_dump($result); // bool(true) — NOT false!
// With && (higher precedence than =) you get what you expect:
$result = $a && $b;
var_dump($result); // bool(false)В первом случае переменной $result сначала присваивается значение $a (true), а часть and $b вычисляется и отбрасывается. Используйте && для boolean-выражений, а and приберегите для случаев, когда низкий приоритет намеренен.
Когда использовать and
- Предпочитайте
&&для вычисления значения boolean-выражения (всё, что вы присваиваете или возвращаете). andудобен как соединитель для управления потоком, где его низкий приоритет безвреден и хорошо читается, например:$db->connect() or die('No DB')используетorтаким же образом.- Внутри условия
if (...)без смешивания=илиorоператорыandи&&ведут себя одинаково.
Связанные операторы
or— логическое ИЛИ (истинно, если хотя бы один операнд истинен).xor— исключающее ИЛИ (истинно, если ровно один операнд истинен).- PHP operators — полный справочник операторов.
- PHP if...else...elseif — построение условной логики.
Заключение
Оператор and объединяет условия и возвращает true только тогда, когда оба истинны, с коротким замыканием при ложном левом операнде. Функционально он идентичен &&, но имеет значительно более низкий приоритет, именно поэтому $x = $a and $b делает не то, что кажется. Используйте && для boolean-значений и выбирайте and намеренно, когда низкий приоритет — это именно то, что вам нужно.