Условные конструкции if/else
<?php
declare(strict_types=1);
$age = 25;
// Basic if
if ($age >= 18) {
echo 'Adult';
}
// if/else
if ($age >= 18) {
echo 'Adult';
} else {
echo 'Minor';
}
// if/elseif/else
if ($age < 13) {
echo 'Child';
} elseif ($age < 18) {
echo 'Teenager';
} else {
echo 'Adult';
}
Альтернативный синтаксис (для шаблонов)
<?php
declare(strict_types=1);
$role = 'admin';
?>
<?php if ($role === 'admin'): ?>
<div class="admin-panel">Admin Panel</div>
<?php elseif ($role === 'editor'): ?>
<div class="editor-panel">Editor Panel</div>
<?php else: ?>
<div class="user-panel">User Panel</div>
<?php endif; ?>
Ловушка экзамена: Обратите внимание:
elseif(слитно) иelse if(раздельно) работают одинаково с фигурными скобками, но в альтернативном синтаксисе (с двоеточием) можно использовать ТОЛЬКОelseifслитно!else if:вызовет ошибку.
<?php
declare(strict_types=1);
$x = 5;
// This is VALID:
if ($x > 0):
echo 'Positive';
elseif ($x < 0): // OK — one word
echo 'Negative';
endif;
// This is INVALID in colon syntax:
// if ($x > 0):
// echo 'Positive';
// else if ($x < 0): // PARSE ERROR — two words!
// echo 'Negative';
// endif;
Тернарный оператор
<?php
declare(strict_types=1);
$age = 20;
// Classic ternary
$status = ($age >= 18) ? 'adult' : 'minor';
// Short ternary (Elvis operator) — PHP 5.3+
$name = '' ?: 'Anonymous'; // 'Anonymous' (empty string is falsy)
$name = 'Alice' ?: 'Anonymous'; // 'Alice'
// Ternary is LEFT-associative in PHP (unlike most languages)
// This is DEPRECATED since PHP 7.4, ERROR in PHP 8.0+
// $value = true ? 'a' : true ? 'b' : 'c';
// Use explicit parentheses:
$value = true ? 'a' : (true ? 'b' : 'c');
Ловушка экзамена: Вложенный тернарный оператор без скобок запрещён с PHP 8.0 (deprecated с 7.4). В PHP 7
$a ? 'x' : $b ? 'y' : 'z'интерпретируется как($a ? 'x' : $b) ? 'y' : 'z'— левоассоциативно, что отличается от большинства языков!
Switch
<?php
declare(strict_types=1);
$color = 'red';
switch ($color) {
case 'red':
echo 'Red color';
break;
case 'blue':
case 'navy': // Fall-through: both match
echo 'Blue shade';
break;
case 'green':
echo 'Green color';
break;
default:
echo 'Unknown color';
break;
}
Подводные камни switch
<?php
declare(strict_types=1);
// Switch uses LOOSE comparison (==), not strict (===)!
$value = 0;
switch ($value) {
case 'hello':
echo 'Matched hello!'; // In PHP 7 this WOULD match!
break; // In PHP 8.0+ it does NOT (changed == behavior)
case 0:
echo 'Matched 0';
break;
}
// Forgetting break — fall-through!
$num = 1;
switch ($num) {
case 1:
echo 'One ';
// Missing break!
case 2:
echo 'Two ';
// Missing break!
case 3:
echo 'Three';
break;
}
// Output: "One Two Three" — all cases execute!
Ловушка экзамена:
switchиспользует нестрогое сравнение (==). Это означает, чтоcase 0:может совпасть со строкой''(пустой). Если нужно строгое сравнение — используйтеmatch(PHP 8.0+).
Match (PHP 8.0+)
<?php
declare(strict_types=1);
$status = 200;
// match uses STRICT comparison (===)
$text = match ($status) {
200 => 'OK',
301 => 'Moved Permanently',
404 => 'Not Found',
500, 503 => 'Server Error', // Multiple values
default => 'Unknown',
};
echo $text; // 'OK'
Отличия match от switch
| Особенность | switch |
match |
|---|---|---|
| Сравнение | == (нестрогое) |
=== (строгое) |
| Возврат значения | Нет (statement) | Да (expression) |
break нужен? |
Да | Нет |
| Fall-through | Да (без break) | Нет |
| Несовпадение | Продолжает работу | UnhandledMatchError |
| Множественные условия | Несколько case |
Через запятую |
<?php
declare(strict_types=1);
// match is an EXPRESSION (returns a value)
$result = match (true) {
$age < 13 => 'child',
$age < 18 => 'teenager',
$age < 65 => 'adult',
default => 'senior',
};
// No match without default = UnhandledMatchError!
$value = 'unknown';
// $result = match ($value) {
// 'a' => 1,
// 'b' => 2,
// };
// UnhandledMatchError: Unhandled match case "unknown"
// match with no argument (match(true))
$temp = 35;
$feeling = match (true) {
$temp < 0 => 'freezing',
$temp < 15 => 'cold',
$temp < 25 => 'comfortable',
$temp < 35 => 'warm',
default => 'hot',
};
Запомни:
match— это выражение (expression), аswitch— инструкция (statement).matchможно присвоить переменной, передать в функцию и т.д. При отсутствии совпадения безdefault— выбрасываетсяUnhandledMatchError.
Циклы
while
<?php
declare(strict_types=1);
$i = 0;
while ($i < 5) {
echo $i . ' '; // 0 1 2 3 4
$i++;
}
do-while
<?php
declare(strict_types=1);
// Body executes AT LEAST once
$i = 10;
do {
echo $i . ' '; // 10 — executes once even though condition is false
$i++;
} while ($i < 5);
Ловушка экзамена:
do-whileВСЕГДА выполняет тело хотя бы один раз, даже если условие изначально ложно. В примере выше тело выполнится один раз и выведет10.
for
<?php
declare(strict_types=1);
// Classic for loop
for ($i = 0; $i < 5; $i++) {
echo $i . ' '; // 0 1 2 3 4
}
// Multiple expressions
for ($i = 0, $j = 10; $i < $j; $i++, $j--) {
echo "($i, $j) "; // (0,10) (1,9) (2,8) (3,7) (4,6)
}
// Infinite loop
// for (;;) {
// // Must break manually
// }
// Performance: calculate count outside the loop!
$items = range(1, 100);
// BAD: count() called on every iteration
for ($i = 0; $i < count($items); $i++) { /* ... */ }
// GOOD: count() called once
$count = count($items);
for ($i = 0; $i < $count; $i++) { /* ... */ }
// ALSO GOOD:
for ($i = 0, $count = count($items); $i < $count; $i++) { /* ... */ }
foreach
<?php
declare(strict_types=1);
$fruits = ['apple', 'banana', 'cherry'];
// Value only
foreach ($fruits as $fruit) {
echo $fruit . ' ';
}
// Key and value
foreach ($fruits as $index => $fruit) {
echo "$index: $fruit\n";
}
// Modifying values by reference
$numbers = [1, 2, 3, 4, 5];
foreach ($numbers as &$num) {
$num *= 2;
}
unset($num); // CRITICAL: unset reference after loop!
// $numbers is now [2, 4, 6, 8, 10]
Ловушка экзамена: После
foreachс ссылкой (&$var) ОБЯЗАТЕЛЬНО вызовитеunset($var)! Без этого переменная$varостаётся ссылкой на последний элемент массива, и дальнейшее использование$varможет непредсказуемо изменить массив.
<?php
declare(strict_types=1);
$arr = [1, 2, 3];
foreach ($arr as &$val) {
// $val is a reference to each element
}
// $val still references $arr[2]!
foreach ($arr as $val) {
// Each iteration overwrites $arr[2] via the reference!
}
// $arr is now [1, 2, 2] — NOT [1, 2, 3]!
// Fix: always unset after reference foreach
$arr = [1, 2, 3];
foreach ($arr as &$val) {
$val *= 10;
}
unset($val); // Properly break the reference
// $arr is now [10, 20, 30]
Деструктуризация в foreach
<?php
declare(strict_types=1);
$users = [
['Alice', 25],
['Bob', 30],
['Charlie', 35],
];
// Array destructuring (PHP 7.1+)
foreach ($users as [$name, $age]) {
echo "$name is $age years old\n";
}
// With keys
$data = [
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 30],
];
foreach ($data as ['name' => $name, 'age' => $age]) {
echo "$name: $age\n";
}
break и continue
<?php
declare(strict_types=1);
// break exits the loop
for ($i = 0; $i < 10; $i++) {
if ($i === 5) {
break;
}
echo $i . ' '; // 0 1 2 3 4
}
// continue skips to the next iteration
for ($i = 0; $i < 10; $i++) {
if ($i % 2 === 0) {
continue;
}
echo $i . ' '; // 1 3 5 7 9
}
// break/continue with depth (nested loops)
for ($i = 0; $i < 3; $i++) {
for ($j = 0; $j < 3; $j++) {
if ($j === 1) {
continue 2; // Continue OUTER loop
}
echo "($i,$j) ";
}
}
// Output: (0,0) (1,0) (2,0)
// break 2 exits both loops
for ($i = 0; $i < 3; $i++) {
for ($j = 0; $j < 3; $j++) {
if ($i === 1 && $j === 1) {
break 2; // Exit BOTH loops
}
echo "($i,$j) ";
}
}
// Output: (0,0) (0,1) (0,2) (1,0)
Запомни:
breakиcontinueпринимают необязательный числовой аргумент — глубину вложенности.break 2выходит из двух вложенных циклов,continue 2переходит к следующей итерации внешнего цикла. Аргумент должен быть целым положительным числом.
goto
<?php
declare(strict_types=1);
// goto exists but is STRONGLY discouraged
goto end;
echo 'This is skipped';
end:
echo 'This is printed';
// Limitations:
// - Cannot jump INTO a loop or switch
// - Cannot jump out of a function
// - Can only jump within the same file/scope
Ловушка экзамена:
gotoсуществует в PHP, но НЕЛЬЗЯ прыгнуть внутрь цикла, switch или функции. Можно только прыгнуть вперёд или назад в пределах одной области видимости. На экзамене могут спросить про ограниченияgoto.
Альтернативный синтаксис
<?php
declare(strict_types=1);
$items = ['a', 'b', 'c'];
$show = true;
?>
<!-- Alternative syntax for templates -->
<?php if ($show): ?>
<ul>
<?php foreach ($items as $item): ?>
<li><?= htmlspecialchars($item) ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php
// Available alternative syntax:
// if/endif
// while/endwhile
// for/endfor
// foreach/endforeach
// switch/endswitch
// NOT available for:
// do-while (no alternative syntax!)
// match (no alternative syntax!)