главная :: основы PHP
Управляющие конструкции
Управляющие конструкции предоставляют в распоряжение программиста средства для построения сложных программ, способных проверять
условия и реагировать на изменения значений входных данных во время работы. Короче говоря, эти структуры управляют выполнением
программы.
Проверка условий
Управляющие конструкции обычно проверяют условия на истинность или ложность, и в зависимости от результата проверки выполняется то
или иное действие. Рассмотрим выражение $а == $b. Это выражение истинно, если $а равно $b, и ложно в противном случае. Результат
истинного выражения считается равным 1, а результат ложного выражения равен 0. Рассмотрим следующий фрагмент:
$а = 5;
$b = 5;
print $а == $b;
В результате выводится значение 1. Если изменить $а или $Ь и присвоить переменной значение, отличное от 5, выводится 0.
if
Команда if представляет собой разновидность команды выбора, которая вычисляет значение выражения и в зависимости от того, будет ли
полученный результат истинным или ложным, выполняет (или не выполняет) блок программного кода. Существует две общих формы
команды i f:
if (выражение) {
блок
}
и
if (выражение) {
блок
}
else {
блок
}
Как упоминалось в предыдущем разделе, проверка условий дает либо истинный, либо ложный результат. Выполнение блоков зависит от
результата проверки, причем блок может состоять как из одной, так и из нескольких команд. В следующем примере после проверки условия
выбирается и выводится одно из двух утверждений:
if ($cooking_weight < 200) {
print "This is enough pasta (< 200g) for 1-2 people";
}
else {
print "That's a lot of pasta. Having a party perhaps?";
}
Если в результате проверки условия выполняется всего одна команда, фигурные скобки не обязательны:
if ($cooking_weight < 100) print "Are you sure this is enough?";
elseif
Команда elseif добавляет в управляющую конструкцию if дополнительный уровень проверки и увеличивает количество условий, на основании
которых принимается решение:
if (выражение) {
блок
}
elseif (выражение) {
блок
}
В РНР существует альтернативное представление команды elself — в виде двух отдельных слов else if. Оба варианта приводят к
одинаковым результатам, а альтернативное представление поддерживается исключительно для удобства. Команда elself особенно
полезна в тех случаях, когда происходит последовательное уточнение проверяемых условий. Обратите внимание: условие elself вычисляется
лишь в том случае, если все предшествующие условия if и elself оказались ложными.
if ($cooking_weight < 200) {
print "This is enough pasta (< 200g) for 1-2 people";
}
elseif ($cooking_weight < 500) {
print "That's a lot of pasta. Having a party perhaps?"; }
}
else {
print "Whoa! Who are you cooking for, a football team?";
}
Вложенные команды if
Вложение команд i f обеспечивает максимальный контроль над проверкой условий. Давайте исследуем эту возможность, усовершенствовав
пример из предыдущих разделов. Предположим, вес продукта должен проверяться лишь в том случае, если речь идет о пасте (макаронных
изделиях):
// Проверить значение $pasta
if ($food == "pasta") {
// Проверить значение $cooking_weight
if ($cooking_weight < 200) {
print "This is enough pasta (< 200g) for 1-2 people";
}
elseif ($cooking_weight < 500) {
print "That's a lot of pasta. Having a party perhaps?";
}
else {
print "Whoa! Who are you cooking for. a football team?";
}
}
Как видно из приведенного кода, вложенные команды if позволяют лучше управлять логикой работы программы. Вскоре, с увеличением
объемов и сложности ваших программ, вы убедитесь, что вложение управляющих конструкций является неоценимым приемом в арсенале
программиста.
Вычисление нескольких условий
При выборе логики работы программы в управляющей структуре можно проверять комбинацию сразу нескольких условий:
if ($cooking_weight < 0) {
print "Invalid cooking weight!";
}
if ( ($cooking_weight > 0) && ($cooking_weight < 200) ) {
print "This is enough pasta (< 200g) for 1-2 people";
}
elseif ( ($cooking_weight > 200) && ($cooking_weight < 500) ) {
print "That's a lot of pasta. Having a party perhaps?";
}
else {
print "Whoa! Who are you cooking for, a football team?";
}
Проверка сложных условий позволяет устанавливать интервальные ограничения, обеспечивающие более четкий контроль над логикой
выполнения программы и уменьшающие количество лишних управляющих конструкций, в результате чего программа становится более
понятной.
Альтернативное ограничение блоков
В управляющих структурах используются специальные ограничители, определяющие границы блоков. Фигурные скобки ({ }) уже упоминались
выше. Для удобства программистов в РНР поддерживается альтернативный формат ограничения блоков:
if (выражение) :
блок
else :
блок
endif;
Следовательно, две приведенных ниже команды if полностью эквивалентны:
if ($а== $b) {
print "Equivalent values!";
}
if ($a == $b) :
print "Equivalent values!";
endif;
while
Конструкция while предназначена для многократного (циклического) выполнения блока команд. Блок команды while выполняется до тех пор,
пока условие цикла остается истинным. Общая форма цикла while выглядит так:
while (выражение) :
блок
endwhile;
Рассмотрим использование цикла while на примере вычисления факториала (n!), где n = 5:
$n = 5;
$nсору = $n;
$factorial = 1; // Установить начальное значение факториала
while ($n > 0) :
$factorial - $n * $factorial;
$n--; // Уменьшить $n на 1
endwhile;
print "The factorial of $ncopy is $factorial.";
Программа выводит следующий результат:
The factorial of 5 is 120.
В этом примере $n уменьшается в конце каждой итерации. Условие цикла не должно быть истинным в тот момент, когда переменная $n
станет равна 0, поскольку величина $factorial умножится на 0 — конечно, этого быть не должно.
В приведенном примере условие цикла следовало бы оптимизировать и привести его к виду $n > 1, поскольку умножать $factorial на 1
бессмысленно — число от этого не изменится. Хотя ускорение работы программы будет ничтожно малым, такие факторы всегда
принимаются во внимание с ростом объема и сложности программ.
do. .while
Цикл do. .while работает почти так же, как и цикл while, описанный в предыдущем разделе, однако в do. .while условие проверяется не в начале,
а в конце каждой итерации. Учтите, что цикл do. .while всегда выполняется хотя бы один раз, а цикл while может вообще не выполняться, если
перед входом в цикл условие окажется ложным:
do:
блок
while (выражение);
Давайте пересмотрим пример с вычислением факториала и перепишем его с использованием конструкции do. .while:
$n = 5:
$ncopy = $n;
$factorial = 1; // Установить начальное значение факториала
do {
$factorial = $n * $factorial;
$n--: // Уменьшить Sn на 1
} while (Sn > 0);
print "The factorial of Sncopy is $factorial.";
При выполнении этого примера будет получен тот же результат, что и при выполнении его прототипа из предыдущего раздела.
В цикле do. .while не поддерживается альтернативный синтаксис (ограничение блоков при помощи : и завершающего ключевого слова),
поэтому блок может заключаться только в фигурные скобки.
for
Цикл for обеспечивает еще одну возможность многократного выполнения блоков. Он отличается от цикла while только тем, что условие
изменяется в самой
управляющей конструкции, а не где-то внутри блока команд. Как и в случае с циклом while, цикл выполняется до тех пор, пока проверяемое
условие остается истинным. Общая форма конструкции for выглядит так:
for (инициализация: условие; приращение) {
блок
}
Условная часть цикла for в действительности состоит из трех компонентов. Инициализация выполняется всего один раз и определяет
начальное значение управляющей переменной цикла. Условие проверяется в начале каждой итерации и определяет, должна ли выполняться
текущая итерация или нет. Наконец, приращение определяет изменение управляющей переменной при каждой итерации. Возможно, термин
«приращение» в данном случае неточен, поскольку переменная может как увеличиваться, так и уменьшаться в соответствии с намерениями
программиста. Следующий пример демонстрирует простейший случай применения цикла for:
for ($i = 10; $1 <- 100: $1 +=10) : // Обратная косая черта предотвращает
print "\$i = $i "; endfor; // возможную интерполяцию переменной $1
Выполнение этого фрагмента дает следующий результат:
$i = 10
$i = 20
$i = 30
$i = 40
$i - 50
$i = 60
$i = 70
$i = 80
$i = 90
$i = 100
В этом примере управляющая переменная $i инициализируется значением 10. Условие заключается в том, что цикл продолжается до тех пор,
пока $i не достигнет или не превысит пороговую величину 100. Наконец, при каждой итерации значение $i увеличивается на 10. В результате
команда print выполняется 10 раз, каждый раз выводя текущее значение $i. Обратите внимание: для увеличения $i на 10 используется оператор
сложения с присваиванием. Для этого есть веские причины, поскольку циклы for в РНР не поддерживают более традиционной записи $i = $i +
10.
Кстати, этот пример можно записать и в другом виде, но с теми же результатами:
for ($i = 10; $i <= 100; print "\$i - $i ". $i+=10);
Многие новички не понимают, зачем создавать несколько разновидностей циклов в языке программирования, будь то РНР или какой-нибудь
другой язык. Почему нельзя обойтись одной циклической конструкцией? Дело в том, что у цикла for существует несколько специфических
особенностей.
Например, вы можете инициализировать несколько переменных одновременно, разделяя команды инициализации запятыми:
for ($x=0,$y=0: $x+$y<10; $x++) :
$У += 2; // Увеличить $у на 2
print "\$y = $y "; // Вывести значение $у
$sum = $x + $y;
print "\surn = $sum "; // Вывести значение $sum
endfor;
Результат:
$y = 2
$sum = 2
Sy = 4
$sum = 5
$y = 6
$sum = 8
$y = 8
$sum = 11
Этот пример выводит текущие значения $y и суммы $х и $у. Как видно из приведенных результатов, выводится значение $sum = 11, хотя эта
сумма выходит за границы условия цикла ($х + $у < 10). Это происходит из-за того, что при входе в данную итерацию переменная $у была
равна 6, а переменная $х была равна 2. Значения переменных соответствовали условию цикла, поэтому $х и $у были присвоены новые
значения, в результате чего была выведена сумма И. При очередной проверке условия сумма 11 превысила пороговое значение 10 и цикл
завершился.
В управляющих выражениях циклов for могут отсутствовать любые компоненты. Например, вы можете передать ранее инициализированную
переменную прямо в цикл, не присваивая ей определенного начального значения. Возможны и другие ситуации — например, приращение
переменной цикла может осуществляться в зависимости от некоторого условия, определяемого в цикле. В этом случае приращение не должно
указываться в управляющем выражении. Пример:
$х = 5:
for (: : $х +=2) :
print " $х ";
if ($x == 15) :
break; // Выйти из цикла for
endif;
endfor;
Результат выглядит так:
5 7 9 11 13 15
Хотя циклические конструкции for и while выполняют практически одинаковые функции, считается, что цикл for делает программу более
наглядной. Это объясняется тем, что программист при виде команды for немедленно получает всю необходимую информацию о механике и
продолжительности цикла. С другой стороны, в командах while приходится тратить лишнее время на поиск обновлений управляющих
переменных — в больших программах это может занимать немало времени.
foreach
Конструкция foreach представляет собой разновидность for, включенную в язык для упрощения перебора элементов массива. Существуют две
разновидности команды foreach, предназначенные для разных типов массивов:
foreach (массив as $элемент) {
блок
}
foreach (массив as $ключ => $элемент) {
блок
}
Например, при выполнении следующего фрагмента:
$menu = аrrау("pasta", "steak", "potatoes", "fish", "fries");
foreach ($menu as $item) {
print "$item ";
}
будет выведен следующий результат:
pasta
steak
potatoes
fish
fries
В этом примере следует обратить внимание на два обстоятельства. Во-первых, конструкция foreach автоматически возвращается в начало
массива (в других циклических конструкциях этого не происходит). Во-вторых, нет необходимости явно увеличивать счетчик или иным
способом переходить к следующему элементу массива — это происходит автоматически при каждой итерации foreach.
Второй вариант используется при работе с ассоциативными массивами:
$wine_inventory = array {
"merlot" => 15,
"zinfandel" => 17,
"sauvignon" => 32
}
foreach ($wine_inventory as $i => $item_count) {
print "$item_count bottles of $i remaining ";
}
В этом случае результат выглядит так:
15 bottles of merlot remaining
17 bottles of zinfandel remaining
32 bottles of sauvignon remaining
Как видно из приведенных примеров, конструкция foreach заметно упрощает работу с массивами. За дополнительной информацией о массивах
обращайтесь к главе 5.
switch
Принцип работы конструкции switch отчасти напоминает if — результат, полученный при вычислении выражения, проверяется по списку
потенциальных совпадений.
Это особенно удобно при проверке нескольких значений, поскольку применение switch делает программу более наглядной и компактной.
Общий формат команды switch:
switch (выражение) {
case (условие):
блок
case (условие):
блок
...
default:
блок
}
Проверяемое условие указывается в круглых скобках после ключевого слова switch. Результат его вычисления последовательно сравнивается с
условиями в секциях case. При обнаружении совпадения выполняется блок соответствующей секции. Если совпадение не будет обнаружено,
выполняется блок необязательной секции default.
Как будет показано в следующих главах, одной из сильнейших сторон РНР является обработка пользовательского ввода. Допустим, программа
отображает раскрывающийся список с несколькими вариантами и каждая строка списка соответствует некоторой команде, выполняемой в
отдельной конструкции case. Реализацию очень удобно построить на использовании команды switch:
$user_input = "recipes"; // Команда,выбранная пользователем
switch ($user_input) :
case("search") :
print "Let's perform a search!";
break;
case("dictionary") :
print "What word would you like to look up?";
break;
case("recipes") :
print "Here is a list of recipes...";
break;
default :
print "Here is the menu...";
break;
endswitch;
Как видно из приведенного фрагмента, команда switch обеспечивает четкую и наглядную организацию кода. Переменная, указанная в условии
switch (в данном примере — $user_input), сравнивается с условиями всех последующих секций case. Если значение, указанное в секции case,
совпадает Со значением сравниваемой переменной, выполняется блок этой секции. Команда break предотвращает проверку дальнейших
секций case и завершает выполнение конструкции switch. Если ни одно из проверенных условий не выполняется, активизируется
необязательная секция default. Если секция default отсутствует и ни одно из условий не выполняется, команда switch просто завершается и
выполнение программы продолжается со следующей команды.
Вы должны помнить, что при отсутствии в секции case команды break (см. следующий раздел) выполнение switch продолжается со следующей
команды до тех пор,
пока не встретится команда break или не будет достигнут конец конструкции switch. Следующий пример демонстрирует последствия
отсутствия забытой команды break: $value = 0.4;
switch($value) :
case (0.4) :
print "value is 0.4 ";
case (0.6) :
print "value is 0.6 ";
break;
case (0.3) :
print "value is 0.3 ";
break;
default :
print "You didn't choose a value!";
break;
endswitch;
Результат выглядит так:
value is 0.4
value is 0.6
Отсутствие команды break привело к тому, что была выполнена не только команда print в той секции, где было найдено совпадение, но и
команда print в следующей секции. Затем выполнение команд конструкции switch прервалось из-за команды switch, следующей за второй
командой print.
Выбор между командами switch и if практически не влияет на быстродействие про-граммы. Решение об использовании той или иной
конструкции является скорее личным делом программиста.
break
Команда break немедленно прерывает выполнение той конструкции while, for или switch, в которой она находится. Эта команда уже
упоминалась в предыдущем разделе, однако прерывание текущего цикла не исчерпывает возможностей команды break. В общем виде
синтаксис break выглядит так:
break n;
Необязательный параметр n определяет количество уровней управляющих конструкций, завершаемых командой break. Например, если команда
break вложена в две команды while и после break стоит цифра 2, происходит немедленный выход из обоих циклов. По умолчанию значение n
равно 1; выход на один уровень может обозначаться как явным указанием 1, так и указанием команды break без параметра. Обратите
внимание: команда i f не относится к числу управляющих конструкций, прерываемых командой break. Об этом следует помнить при
использовании необязательного параметра п.
Рассмотрим пример использования команды break в цикле foreach:
$arr = array(14, 12, 128, 34, 5);
$magic number = 128:
foreach ($arr as $val) :
if (Sval == $magic_number) :
print "The magic number is in the array!";
break;
endif;
print "val is Sval ";
endforeach;
Если значение $magic_number присутствует в массиве $аrr (как в приведенном примере), поиск прерывается. Результат выглядит так:
val is 14
val is 12
The magic number is in the array!
Приведенный пример всего лишь демонстрирует использование команды break. В РНР существует стандартная функция in_array( ),
предназначенная для поиска заранее заданной величины в массиве; эта функция подробно описана в главе 5.
continue
Остается рассмотреть еще одну управляющую конструкцию РНР — continue. При выполнении команды continue в цикле пропускаются все
оставшиеся команды текущей итерации и немедленно начинается новая итерация. Синтаксис команды continue в общем виде:
continue n;
Необязательный параметр n указывает, на сколько уровней внешних циклов распространяется действие continue.
Рассмотрим пример использования команды continue. Допустим, вы хотите сосчитать простые числа в интервале от 0 до некоторой заданной
границы. Простоты ради предположим, что у нас имеется функция is_prime(), которая проверяет, является число простым или нет:
$boundary = 558;
for ($i = 0; $i <= $boundary: $i++) :
if (! is_prime($i)) :
continue;
endif;
$prime_counter++;
endfor;
Если проверяемое число является простым, блок команды if обходится и переменная $prime_counter увеличивается. В противном случае
выполняется команда continue, в результате чего происходит немедленный переход в начало следующей итерации.
Использование continue в длинных и сложных алгоритмах приводит к появлению запу- танного и невразумительного кода. В подобных
случаях использовать continue не рекомендуется.
Команда continue не является безусловно необходимой в программах, поскольку аналогичного эффекта можно добиться при помощи команды if.
|