Перейти к содержимому

5. Операторы

Операторы — это символы, которые выполняют действия над значениями и переменными. PHP предоставляет богатый набор операторов для арифметических, логических, сравнительных и других операций.

  • Арифметические операторы
  • Операторы присваивания
  • Операторы сравнения
  • Логические операторы
  • Инкремент и декремент
  • Строковые операторы
  • Тернарный оператор
  • Оператор объединения с null
  • Spaceship operator (PHP 7+)

Выполняют математические операции.

<?php
$a = 10;
$b = 3;
echo $a + $b; // 13 (сложение)
echo $a - $b; // 7 (вычитание)
echo $a * $b; // 30 (умножение)
echo $a / $b; // 3.333... (деление)
echo $a % $b; // 1 (остаток от деления - modulo)
echo $a ** $b; // 1000 (возведение в степень, PHP 5.6+)
// Целочисленное деление (PHP 7+)
echo intdiv($a, $b); // 3
// Унарные операторы
echo +$a; // 10 (плюс)
echo -$a; // -10 (минус)
?>
```text
### Практические примеры
```php
<?php
// Расчет скидки
$price = 1000;
$discount_percent = 15;
$discount = $price * $discount_percent / 100;
$final_price = $price - $discount;
echo "Цена: $price руб<br>";
echo "Скидка: $discount руб ($discount_percent%)<br>";
echo "Итого: $final_price руб<br>";
// Определение четности
$number = 42;
if ($number % 2 == 0) {
echo "$number - четное число";
} else {
echo "$number - нечетное число";
}
// Разбивка суммы на купюры
$amount = 1273;
$thousands = intdiv($amount, 1000);
$hundreds = intdiv($amount % 1000, 100);
$tens = intdiv($amount % 100, 10);
$ones = $amount % 10;
echo "1000: $thousands, 100: $hundreds, 10: $tens, 1: $ones";
?>
```text
## Операторы присваивания
Присваивают значения переменным.
```php
<?php
// Простое присваивание
$x = 10;
// Присваивание с операцией
$x += 5; // $x = $x + 5 → 15
$x -= 3; // $x = $x - 3 → 12
$x *= 2; // $x = $x * 2 → 24
$x /= 4; // $x = $x / 4 → 6
$x %= 4; // $x = $x % 4 → 2
$x **= 3; // $x = $x ** 3 → 8
// Строковая конкатенация
$name = "Иван";
$name .= " Петров"; // $name = $name . " Петров"
echo $name; // "Иван Петров"
// Присваивание по ссылке
$a = 10;
$b = &$a; // $b ссылается на $a
$b = 20;
echo $a; // 20 (изменился вместе с $b!)
?>
```text
### Присваивание по значению vs по ссылке
```php
<?php
// Присваивание по значению (копируется)
$original = ["apple", "banana"];
$copy = $original;
$copy[] = "orange";
print_r($original); // ["apple", "banana"]
print_r($copy); // ["apple", "banana", "orange"]
// Присваивание по ссылке (НЕ копируется)
$original = ["apple", "banana"];
$reference = &$original;
$reference[] = "orange";
print_r($original); // ["apple", "banana", "orange"] - изменился!
print_r($reference); // ["apple", "banana", "orange"]
?>
```text
## Операторы сравнения
Сравнивают два значения и возвращают `true` или `false`.
```php
<?php
$a = 10;
$b = "10";
// Равенство (с приведением типов)
var_dump($a == $b); // bool(true) - значения равны
// Идентичность (без приведения типов)
var_dump($a === $b); // bool(false) - разные типы
// Неравенство
var_dump($a != $b); // bool(false)
var_dump($a <> $b); // bool(false) - то же что !=
// Не идентичны
var_dump($a !== $b); // bool(true) - разные типы
// Больше/меньше
var_dump(5 > 3); // bool(true)
var_dump(5 < 3); // bool(false)
var_dump(5 >= 5); // bool(true)
var_dump(5 <= 4); // bool(false)
// Spaceship operator (PHP 7+)
echo 5 <=> 3; // 1 (5 больше 3)
echo 3 <=> 5; // -1 (3 меньше 5)
echo 5 <=> 5; // 0 (равны)
?>
```text
### Важно: == vs ===
```php
<?php
// ⚠️ == сравнивает значения (с приведением типов)
var_dump(0 == false); // bool(true)
var_dump(0 == ""); // bool(true)
var_dump(0 == "0"); // bool(true)
var_dump(false == ""); // bool(true)
var_dump("10" == 10); // bool(true)
// ✅ === сравнивает значения И типы (строгое сравнение)
var_dump(0 === false); // bool(false)
var_dump(0 === ""); // bool(false)
var_dump(0 === "0"); // bool(false)
var_dump("10" === 10); // bool(false)
var_dump(10 === 10); // bool(true)
// Рекомендация: используйте === для избежания багов
$user_input = "0";
if ($user_input == false) {
echo "Это сработает, хотя строка '0' существует!";
}
if ($user_input === false) {
echo "Это НЕ сработает (правильно)";
}
?>
```text
### Сравнение массивов
```php
<?php
$a = ["x" => 1, "y" => 2];
$b = ["y" => 2, "x" => 1];
$c = ["x" => 1, "y" => 2];
var_dump($a == $b); // bool(true) - одинаковые пары ключ=>значение
var_dump($a === $b); // bool(false) - разный порядок
var_dump($a === $c); // bool(true) - идентичны
?>
```text
## Логические операторы
Комбинируют булевы значения.
```php
<?php
$a = true;
$b = false;
// AND (и) - истина если оба true
var_dump($a && $b); // bool(false)
var_dump($a and $b); // bool(false) - то же, но низкий приоритет
// OR (или) - истина если хотя бы один true
var_dump($a || $b); // bool(true)
var_dump($a or $b); // bool(true) - то же, но низкий приоритет
// XOR (исключающее или) - истина если ТОЛЬКО ОДИН true
var_dump($a xor $b); // bool(true)
var_dump($a xor $a); // bool(false)
// NOT (отрицание)
var_dump(!$a); // bool(false)
var_dump(!$b); // bool(true)
?>
```text
### Практическое применение
```php
<?php
$age = 25;
$has_license = true;
$has_insurance = true;
// Можно ли арендовать машину?
if ($age >= 21 && $has_license && $has_insurance) {
echo "Вы можете арендовать автомобиль";
} else {
echo "Аренда недоступна";
}
// Скидка для студентов или пенсионеров
$is_student = true;
$is_pensioner = false;
if ($is_student || $is_pensioner) {
echo "Вам доступна скидка 20%";
}
// Проверка прав доступа
$is_admin = false;
$is_moderator = true;
if ($is_admin || $is_moderator) {
echo "У вас есть права модерации";
}
?>
```text
### Короткое замыкание (short-circuit evaluation)
```php
<?php
// && прекращает выполнение если первое условие false
$x = false;
$y = true;
// functionA() НЕ вызовется, так как $x уже false
if ($x && functionA()) {
// ...
}
// || прекращает выполнение если первое условие true
if ($y || functionB()) {
// functionB() НЕ вызовется, так как $y уже true
}
// Практическое применение
$user = getUserById($id);
// Безопасная проверка вложенного свойства
if ($user && $user->isActive()) {
echo "Пользователь активен";
}
// Если $user = null, isActive() не вызовется (не будет ошибки)
?>
```text
## Инкремент и декремент
Увеличение/уменьшение на 1.
```php
<?php
$a = 5;
// Постфиксный инкремент (сначала возвращает, потом увеличивает)
echo $a++; // 5 (вернет 5, потом увеличит до 6)
echo $a; // 6
// Префиксный инкремент (сначала увеличивает, потом возвращает)
echo ++$a; // 7 (сначала увеличит до 7, потом вернет)
echo $a; // 7
// То же с декрементом
$b = 5;
echo $b--; // 5
echo $b; // 4
echo --$b; // 3
echo $b; // 3
?>
```text
### Практическое применение
```php
<?php
// Счетчик в цикле
$counter = 0;
while ($counter < 5) {
echo "Итерация $counter<br>";
$counter++;
}
// Обработка массива
$items = ["apple", "banana", "orange"];
$index = 0;
while ($index < count($items)) {
echo $items[$index] . "<br>";
$index++;
}
// Обратный счетчик
$countdown = 10;
while ($countdown > 0) {
echo "$countdown...<br>";
$countdown--;
}
echo "Поехали!";
?>
```text
### Разница между $i++ и ++$i
```php
<?php
// В присваивании разница есть
$a = 5;
$b = $a++; // $b = 5, потом $a = 6
echo "a=$a, b=$b"; // a=6, b=5
$c = 5;
$d = ++$c; // $c = 6, потом $d = 6
echo "c=$c, d=$d"; // c=6, d=6
// В циклах обычно без разницы
for ($i = 0; $i < 5; $i++) { } // ✅
for ($i = 0; $i < 5; ++$i) { } // ✅ то же самое
?>
```text
## Строковые операторы
Работа со строками.
```php
<?php
// Конкатенация (.)
$firstName = "Иван";
$lastName = "Петров";
$fullName = $firstName . " " . $lastName;
echo $fullName; // "Иван Петров"
// Конкатенация с присваиванием (.=)
$message = "Привет";
$message .= ", ";
$message .= "мир!";
echo $message; // "Привет, мир!"
// Построение HTML
$html = "<div class='card'>";
$html .= "<h2>Заголовок</h2>";
$html .= "<p>Параграф</p>";
$html .= "</div>";
echo $html;
?>
```text
### Интерполяция vs конкатенация
```php
<?php
$name = "Алексей";
$age = 25;
// Интерполяция (внутри двойных кавычек)
echo "Меня зовут $name, мне $age лет";
// Конкатенация
echo 'Меня зовут ' . $name . ', мне ' . $age . ' лет';
// Сложные выражения требуют конкатенации или фигурных скобок
$user = ["name" => "Иван"];
echo "Пользователь: {$user['name']}"; // ✅
echo "Пользователь: " . $user['name']; // ✅
?>
```text
## Тернарный оператор
Краткая форма условного оператора.
```php
<?php
// Синтаксис: условие ? значение_если_true : значение_если_false
$age = 20;
$status = ($age >= 18) ? "взрослый" : "несовершеннолетний";
echo $status; // "взрослый"
// Обычный if/else (то же самое)
if ($age >= 18) {
$status = "взрослый";
} else {
$status = "несовершеннолетний";
}
// Примеры
$is_logged_in = true;
echo $is_logged_in ? "Добро пожаловать" : "Войдите в систему";
$score = 85;
$grade = ($score >= 90) ? "A" :
($score >= 80) ? "B" :
($score >= 70) ? "C" : "F";
echo $grade; // "B"
?>
```text
### Elvis operator (PHP 5.3+)
Сокращенный тернарный оператор.
```php
<?php
// Обычный тернарный
$username = isset($_GET['user']) ? $_GET['user'] : 'Гость';
// Elvis operator (?: без средней части)
$username = $_GET['user'] ?: 'Гость';
// Эквивалентно: $_GET['user'] ? $_GET['user'] : 'Гость'
// Примеры
$name = $user->getName() ?: 'Аноним';
$title = $post_title ?: 'Без названия';
?>
```text
## Null Coalescing Operator (PHP 7+)
Оператор объединения с null (`??`).
```php
<?php
// Вернет первое не-null значение
$username = $_GET['user'] ?? $_POST['user'] ?? 'Гость';
// Старый способ (многословный)
$username = isset($_GET['user']) ? $_GET['user'] :
(isset($_POST['user']) ? $_POST['user'] : 'Гость');
// Примеры
$page = $_GET['page'] ?? 1;
$limit = $_GET['limit'] ?? 10;
$sort = $_GET['sort'] ?? 'date';
echo "Страница: $page, на странице: $limit, сортировка: $sort";
// Цепочка ?? (берет первое не-null)
$config = $custom_config ?? $default_config ?? $fallback_config ?? [];
?>
```text
### ?? vs ?:
```php
<?php
// ?? проверяет только на null/несуществование
// ?: проверяет на falsy значение
$value = 0;
echo $value ?: 'default'; // "default" (0 falsy)
echo $value ?? 'default'; // "0" (0 не null)
$value = null;
echo $value ?? 'default'; // "default" (null)
// Рекомендация: используйте ?? для проверки существования переменной
?>
```text
### Null coalescing assignment (PHP 7.4+)
```php
<?php
// ??= присваивает если переменная null или не существует
$config['theme'] ??= 'default';
// Эквивалентно:
// $config['theme'] = $config['theme'] ?? 'default';
// Примеры
$settings['lang'] ??= 'ru';
$settings['timezone'] ??= 'Europe/Moscow';
$settings['perPage'] ??= 20;
?>
```text
## Приоритет операторов
Порядок выполнения операторов.
```php
<?php
// * и / выполняются раньше + и -
echo 2 + 3 * 4; // 14 (не 20)
echo (2 + 3) * 4; // 20 (скобки изменяют приоритет)
// && выполняется раньше ||
$a = true;
$b = false;
$c = true;
echo $a || $b && $c; // true (сначала $b && $c, потом $a || result)
// Используйте скобки для ясности
echo ($a || $b) && $c; // true
// Приоритет присваивания
$x = $y = 5; // Сначала $y = 5, потом $x = $y
echo $x; // 5
?>
```text
### Таблица приоритетов (от высокого к низкому)
```text
1. ()
2. **
3. ++ -- (префиксный)
4. !
5. * / %
6. + - .
7. < <= > >=
8. == != === !== <=>
9. &&
10. ||
11. ??
12. ? :
13. = += -= *= /= .= и т.д.
```text
**Совет:** При малейшем сомнении используйте скобки!
## Битовые операторы
Работа с битами (редко используются в веб-разработке).
```php
<?php
$a = 5; // 0101 в двоичной системе
$b = 3; // 0011
echo $a & $b; // 1 (AND: 0001)
echo $a | $b; // 7 (OR: 0111)
echo $a ^ $b; // 6 (XOR: 0110)
echo ~$a; // -6 (NOT: инверсия битов)
echo $a << 1; // 10 (сдвиг влево: 1010)
echo $a >> 1; // 2 (сдвиг вправо: 0010)
// Практическое применение: флаги прав доступа
define('READ', 1); // 0001
define('WRITE', 2); // 0010
define('EXECUTE', 4); // 0100
define('DELETE', 8); // 1000
$permissions = READ | WRITE; // 0011 (чтение и запись)
if ($permissions & READ) {
echo "Есть право на чтение";
}
?>
```text
## WordPress контекст
Операторы активно используются в WordPress.
### Проверки и условия
```php
<?php
// Проверка авторизации
if (is_user_logged_in() && current_user_can('edit_posts')) {
echo '<a href="' . admin_url('post-new.php') . '">Создать пост</a>';
}
// Условный вывод
$author_name = get_the_author() ?: 'Аноним';
$post_thumbnail = get_the_post_thumbnail() ?: '<img src="' . get_template_directory_uri() . '/img/default.jpg">';
// Пагинация
$paged = get_query_var('paged') ?: 1;
$posts_per_page = get_option('posts_per_page') ?? 10;
$args = [
'post_type' => 'post',
'posts_per_page' => $posts_per_page,
'paged' => $paged
];
?>
```text
### Фильтрация и санитизация
```php
<?php
// Получение и проверка данных
$post_id = absint($_GET['post_id'] ?? 0);
$action = sanitize_text_field($_GET['action'] ?? '');
if ($post_id > 0 && $action === 'edit' && current_user_can('edit_post', $post_id)) {
// Редактирование поста
} else {
wp_die('Недостаточно прав');
}
// Короткий код с параметрами
function my_shortcode($atts) {
$atts = shortcode_atts([
'title' => 'Заголовок по умолчанию',
'count' => 5,
'show_date' => false
], $atts);
$count = absint($atts['count']);
$show_date = filter_var($atts['show_date'], FILTER_VALIDATE_BOOLEAN);
// ...
}
add_shortcode('my_shortcode', 'my_shortcode');
?>
```text
## Практика
### Задание 1: Калькулятор
Создайте простой калькулятор с использованием всех арифметических операторов.
```php
<?php
$a = 20;
$b = 4;
echo "$a + $b = " . ($a + $b) . "<br>";
echo "$a - $b = " . ($a - $b) . "<br>";
echo "$a * $b = " . ($a * $b) . "<br>";
echo "$a / $b = " . ($a / $b) . "<br>";
echo "$a % $b = " . ($a % $b) . "<br>";
echo "$a ** $b = " . ($a ** $b) . "<br>";
?>
```text
### Задание 2: Проверка возраста
Создайте скрипт, который проверяет возраст и выводит категорию (ребенок/подросток/взрослый/пенсионер).
### Задание 3: Система скидок
Рассчитайте финальную цену с учетом скидок:
- Базовая скидка 10%
- Дополнительно 5% если сумма > 5000
- Дополнительно 3% если клиент VIP
### Задание 4: Валидация формы
Проверьте данные формы с помощью логических операторов.
```php
<?php
$name = $_POST['name'] ?? '';
$email = $_POST['email'] ?? '';
$age = $_POST['age'] ?? 0;
$is_valid = !empty($name) &&
filter_var($email, FILTER_VALIDATE_EMAIL) &&
$age >= 18;
if ($is_valid) {
echo "Форма валидна";
} else {
echo "Исправьте ошибки";
}
?>
```text
### Задание 5: Тернарные операторы
Перепишите следующий код используя тернарный оператор:
```php
<?php
$score = 75;
if ($score >= 90) {
$grade = "A";
} elseif ($score >= 80) {
$grade = "B";
} elseif ($score >= 70) {
$grade = "C";
} else {
$grade = "F";
}
// Ваше решение здесь
?>
```text
## Онлайн-редакторы
Тестируйте примеры:
- **PHPSandbox**: https://phpsandbox.io/
- **3v4l**: https://3v4l.org/
## Итоги
В этом уроке вы изучили:
✅ **Арифметические операторы** — +, -, *, /, %, **
✅ **Операторы присваивания** — =, +=, -=, .=
✅ **Операторы сравнения** — ==, ===, !=, !==, <, >
✅ **Логические операторы** — &&, ||, !, xor
✅ **Инкремент/декремент** — ++, --
✅ **Тернарный оператор** — ? :
✅ **Null coalescing** — ??
✅ **Приоритет операторов** — порядок выполнения
### Следующий шаг
Теперь научимся управлять потоком выполнения: [Условия](/php/conditions/)
### Ключевые моменты
1. **=== вместо ==** — строгое сравнение безопаснее
2. **?? для переменных** — проверка существования
3. **Скобки для ясности** — не полагайтесь на приоритет
4. **++$i vs $i++** — в циклах разницы нет
5. **Логические операторы короткое замыкание** — используйте для оптимизации
**Совет:** Операторы — основа логики в программировании. Практикуйтесь с разными комбинациями!
---
**Готовы двигаться дальше?** Переходите к следующему уроку: [Условия](/php/conditions/)