На главную Назад
Добро пожаловать, уважаемый посетитель!

 

ГЛАВА 3

Выражения, операторы и управляющиеконструкции

В этой главе представлены некоторыеаспекты, играющие исключительно важнуюроль в любом языке программирования, - аименно, выражения, операторы и управляющиеконструкции. Этот материал необходим впервую очередь при создании больших исложных приложений РНР. Если вы уже знакомыс такими языками, как С и Java, эта глава всеголишь напомнит известные вам понятия. Еслиже вы впервые встречаетесь с этимитерминами и понятиями, которые ониобозначают, знание материала этой главыбудет безусловно необходимо для пониманияостальных глав книги.

Выражения

Выражение описываетнекоторое действие, выполняемое впрограмме. Каждое выражение состоит покрайней мере из одного операнда и одногоили нескольких операторов. Прежде чемпереходить к примерам, демонстрирующимиспользование выражений, необходимопоближе познакомиться с операторами иоперандами.

Операнды

Операнд представляетсобой некоторую величину, обрабатываемую впрограмме. Операнды могут относиться клюбому типу данных, представленному в главе2. Вероятно, вы уже знакомы с концепциямиобработки и использования операндов нетолько в повседневных математическихвычислениях, но и по прежнему опытупрограммирования. Примеры операндов:

$а++; // $а - операнд

$sum = $val1 + $val2; //$sum. $val1 и $val2 - операнды

Операторы

Оператор представляетсобой символическое обозначениенекоторого действия, выполняемого соперандами в выражении. Многие операторыизвестны любому программисту, но вы должныпомнить, что РНР выполняет автоматическое преобразование типов на основании типаоператора, объединяющего два операнда, - вдругих языках программирования этопроисходит не всегда.

Приоритет и ассоциативность операторовявляются важными характеристиками языкапрограммирования (см. раздел <Ассоциативностьоператоров> этой главы). В табл. 3.1 приведенполный список всех операторов,упорядоченных по убыванию приоритета.Приоритет, ассоциативность и самиоператоры подробно рассматриваются вразделах, следующих за таблицей.

Таблица 3.1. ОператорыРНР

ОператорАссоциативностьЦель
( )-Изменение приоритета
new-Создание экземпляров объектов
! ~П

Логическое отрицание, поразрядноеотрицание

++--ПИнкремент, декремент
@ПМаскировка ошибок
/ * %ЛДеление, умножение, остаток
+ - .ЛСложение, вычитание, конкатенация
<<  >>ЛСдвиг влево, сдвиг вправо (поразрядный)
< <=  >  >=-Меньше, меньше или равно, больше, большеили равно
== !=  ===  <>-Равно, не равно, идентично, не равно
&  ^  |ЛПоразрядные операции AND, XOR и OR
&& ||ЛЛогические операции AND и OR
?:ПТернарный оператор
=  +=  *=  /=  .=ПОператоры присваивания
%=  &=  |=  ^=  
<<=  >>=  
AND XOR ORЛЛогические операции AND, XOR и OR

После знакомства с концепциямиоператоров и операндов следующие примерывыражений выглядят значительно понятнее:

$а = 5;  // Присвоить целое число 5 переменной $а

$а = "5":  // Присвоить строковую величину "5"переменной $а

$sum = 50 + $some_int; // Присвоить сумму 50 + $some_int переменной $sum

Swine = "Zinfandel";  // Присвоить строку "Zinfandel" переменной$wine

$inventory++:  // Увеличить значение $inventory на 1

Объединяя операторы и операнды, выполучите более сложные выражения длявыполнения нетривиальных вычислений.Пример:

$total_cost = $cqst + (Scost * 0.06): // прибавить к цене 6-процентныйналог

Приоритет операторов

Приоритет являетсяхарактеристикой операторов, определяющейпорядок выполнения действий с окружающимиоперандами. В РНР используются те жеправила приоритета, что и в школьном курсематематики. Пример:

$total_cost = $cost + $cost * 0.06;

Приведенная команда эквивалентнаследующей:

$total cost = $cost + ($cost * 0.06);

Это объясняется тем, что операторумножения обладает более высокимприоритетом по сравнению с операторомсложения.

Ассоциативность операторов

Ассоциативность оператораопределяет последовательность выполненияоператоров с одинаковым приоритетом (см.табл. 3.1). Выполнение может происходить вдвух направлениях: либо слева направо, либосправа налево. При ассоциативности первоготипа операции, входящие в выражение,выполняются слева направо. Например,команда

$value =3*4*5*7*2;

эквивалентна следующей команде:

$value = ((((3 * 4) * 5) * 7) * 2);

Результат вычислений равен 840. Этообъясняется тем, что оператор умножения (*)обладает левосторонней ассоциативностью.Операторы с правостороннейассоциативностью и одинаковым приоритетомобрабатываются справа налево. Например,фрагмент

$с = 5;

$value = $а - $b - $с;

эквивалентен фрагменту

$c = 5;

$value = ($а - ($b - $с));

При обработке этого выражения переменным$value, $a, $b и $с будет присвоено значение 5. Этообъясняется тем, что оператор присваивания(=) обладает правостороннейассоциативностью.

Математические операторы

Математические операторы (табл.3.2) предназначены для выполнения различныхматематических операций и частоприменяются в большинстве программ РНР. Ксчастью, их использование обходится безпроблем.

Таблица 3.2. Математическиеоператоры

Пример

Название

Результат

$а + $b

Сложение

Сумма $а и $b

$а-$b

Вычитание

Разность $а и $b

$а*$b

Умножение

Произведение $а и $b

$а/$b

Деление

Частное от деления $а на $b

$а % $b

Остаток

Остаток от деления $а на $b

РНР содержит широкий ассортиментстандартных математических функций длявыполнения основных преобразований ивычисления логарифмов, квадратных корней,геометрических величин и т. д. Заобновленным списком таких функцийобращайтесь к документации.

Операторы присваивания

Операторы присваивания задаютновое значение переменной. В простейшемварианте оператор присваиванияограничивается изменением величины, вдругих вариантах (называемых сокращеннымиоператорами присваивания) передприсваиванием выполняется некотораяоперация. Примеры таких операторовприведены в табл. 3.3.

Таблица 3.3.Операторыприсваивания

Пример НазваниеРезультат
$а = 5;  ПрисваиваниеПеременная $а равна 5 
$а += 5;  Сложение с присваиванием Переменная $а равнасумме $а и 5
$а *= 5;  Умножение с присваиванием Переменная $а равна произведению$а и 5
$а/=5; Деление с присваиваниемПеременная $а равна частному отделения$а на 5
$а .= 5;  Конкатенация с присваиваниемПеременная $а равна конкатенации $а и 5

Умеренное использование операторовприсваивания обеспечивает более наглядныйи компактный код.

Строковые операторы

Строковые операторы РНР(табл. 3.4) обеспечивают удобные средстваконкатенации (то есть слияния) строк.Существует два строковых оператора:оператор конкатенации (.) и операторконкатенации с присваиванием (.=), описанныйв предыдущем разделе <Операторыприсваивания>.

Конкатенациейназывается объединение двух и болееобъектов в единое целое.

Таблица 3.4. Строковыеоператоры

Пример

Название

Результат

$a = "abc"."def"

Конкатенация

Переменной $а присваивается результатконкатенации $а и $b

 $а - "ghijkl"

 Конкатенация сприсваиванием

Переменной $априсваивается результат конкатенацииее текущего значения со строкой "ghijkl"

Пример использования строковыхоператоров:

// $а присваивается строковое значение "Spaghetti& Meatballs" $а = "Spaghetti" . "& Meatballs"

// $а присваивается строковое значение "Spaghetti& Meatballs are delicious" $a .= "are delicious";

Конечно, два строковых оператора неисчерпывают всех возможностей РНР пообработке строк. За полной информацией обэтих возможностях обращайтесь к главе 8.

Операторы инкремента и декремента

Удобные вспомогательные операторы инкремента(++) и декремента(--),приведенные в табл. 3.5, делают программуболее наглядной и обеспечивают укороченнуюзапись для увеличения или уменьшениятекущего значения переменной на 1.

Таблица 3.5. Операторыинкремента и декремента

ПримерНазваниеРезультат
++$а, $а++ Инкремент Переменная $аувеличивается на 1
--$а, $а-- ДекрементПеременная$а уменьшается на 1

Интересный факт: эти операторы могутрасполагаться как слева, так и справа отоперанда. Действия, выполняемые оператором,зависят от того, с какой стороны от операндаон находится. Рассмотрим следующий пример:

$inventory = 15;  // Присвоить Sinventory целое число 15

$old_inv = Sinventory--;  // СНАЧАЛАприсвоить $old_inv значение

// Sinventory. а ЗАТЕМуменьшить Sinventory.

$orig_iinventory = ++inventory;// СНАЧАЛАувеличить Sinventory. а ЗАТЕМ

// присвоить увеличенное значение Sinventory

//переменной $orig_inventory.

Как видите, расположение операторовинкремента и декремента оказывает сильноевлияние на результат вычислений.

Логические операторы

Логические операторы (табл.3.6) наряду с математическими операторамииграют важную роль в любом приложении РНР,обеспечивая средства для принятия решенийв зависимости от значения переменных.Логические операторы позволяют управлятьпорядком выполнения команд в программе ичасто используются в управляющихконструкциях (таких, как условная команда i f,а также циклы for и while).

Таблица 3.6. Логическиеоператоры

Пример

Название

Результат

$а && $b

Конъюнкция

Истина, если истинны оба операнда ,

$aAND$b

Конъюнкция

Истина, если истинны оба операнда

$а И $b

Дизъюнкция

Истина, если истинен хотя бы один изоперандов

$а OR $b

Дизъюнкция

Истина, если истинен хотя бы один изоперандов

!$а

Отрицание

Истина, если значение $а ложно

NOT !$a

Отрицание

Истина, если значение $а ложно

$а XOR $b

Исключающая дизъюнкция

Истина, если истинен только один изоперандов

Логические операторы часто используютсядля проверки результата вызова функций:

file_exists("filename.txt") OR print "File does not exist!";

Возможен один из двух вариантов:

  • файл filename.txt существует;
  • будет выведено сообщение: .

Операторы равенства

Операторы равенства (табл.3.7) предназначены для сравнения двухвеличин и проверки их эквивалентности.

Таблица 3.7. Операторыравенства

Пример

Название

Результат 

$a==$bПроверка равенстваИстина, если $а и $b равны
$а!= $b Проверканеравенства Истина, если $аи $b не равны

$а === $b

Проверка идентичности

Истина, если $а и $b равны иимеют одинаковый тип

Даже опытные программисты частодопускают одну распространенную ошибку -они пытаются проверять равенство двухвеличин, используя всего один знакравенства (например, $а = $b). Помните, притакой записи значение $b присваивается $а, ижелаемый результат небудет достигнут.

Операторы сравнения

Операторы сравнения (табл.3.8), как и логические операторы, позволяютуправлять логикой программы и приниматьрешения при сравнении двух и болеепеременных.

Таблица 3.8. Операторысравнения

Пример

Название

Результат

$a<$b

Меньше

Истина, если переменная $а меньше $b

$a>$b

Больше

Истина, если переменная $а больше $b

$a <= $b

Меньше или равно

Истина, если переменная $а меньше илиравна $b

$a >= $b

Больше или равно

Истина, если переменная $а больше илиравна $b

($a-12)?5: -1

Тернарный оператор

Если переменная $а равна 12,возвращается значение 5, а если не равна - возвращается 1

Обратите внимание: операторы сравненияпредназначены для работы только счисловыми значениями. Хотя возникаетискушение воспользоваться ими длясравнения строк, результат, скорее всего,окажется неверным. В РНР существуютстандартные функции для сравнениястроковых величин. Эти функции подробнорассматриваются в главе 8.

Поразрядные операторы

Поразрядные операторы выполняютоперации с целыми числами на уровнеотдельных битов, составляющих число. Чтобылучше понять принцип их работы, необходимоиметь хотя бы общее представление одвоичном представлении десятичных чисел. Втабл. 3.9 приведены примеры десятичных чисели соответствующих им двоичныхпредставлений.

Таблица 3.9. Десятичныечисла и их двоичные представления

Десятичное целоеДвоичное представление
210
5101
101010
121100
14510010001
1 452 0121011000100111111101100

Поразрядные операторы, перечисленные втабл. 3.10, представляют собой особый случайлогических операторов, однако они приводятк совершенно иным результатам.

Таблица 3.10. Поразрядныеоператоры

Пример

Название

Результат

$а&$b

Конъюнкция

С битами, находящимися в одинаковыхразрядах $а и $b, выполняется операция конъюнкции

$а|$Ь

Дизъюнкция

С битами, находящимися в одинаковыхразрядах $а и $b, выполняется операция дизъюнкции

$а^$b

 

Исключающая

С битами, находящимися в одинаковыхразрядах $а и $b, выполняется операция исключающейдизъюнкции

~$b

Отрицание

Все разряды переменной $bинвертируются

$а << $b

Сдвиг влево

Переменной $а присваивается значение $b,сдвинутое влево на два бита

$а >> $b

Сдвиг вправо

Переменной $а присваивается значение $b,сдвинутое вправо на два бита

Если вам захочется больше узнать одвоичном представлении и поразрядныхоператорах, я рекомендую обратиться кобширному электронному справочникуРэндалла Хайда (Randall Hyde) , доступному по адресу http://webster.cs.ucr.edu/Page_asm/Page_asm.html.Это лучший из ресурсов, которые мне когда-либовстречались в Web.

Управляющие конструкции

Управляющие конструкции предоставляютв распоряжение программиста средства дляпостроения сложных программ, способныхпроверять условия и реагировать наизменения значений входных данных во времяработы. Короче говоря, эти структурыуправляют выполнением программы.

Проверка условий

Управляющие конструкции обычно проверяютусловия на истинность или ложность, и взависимости от результата проверкивыполняется то или иное действие.Рассмотрим выражение $а == $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 "Thefactorial of Sncopy is $factorial.";

При выполнении этого примера будетполучен тот же результат, что и привыполнении его прототипа из предыдущегораздела.

Вцикле do. .while не поддерживаетсяальтернативный синтаксис (ограничениеблоков при помощи : и завершающегоключевого слова), поэтому блок можетзаключаться только в фигурные скобки.

for

Цикл for обеспечивает еще одну возможностьмногократного выполнения блоков. Онотличается от цикла while только тем, чтоусловие изменяется в самой

управляющей конструкции, а не где-товнутри блока команд. Как и в случае с цикломwhile, цикл выполняется до тех пор, покапроверяемое условие остается истинным.Общая форма конструкции for выглядит так:

for (инициализация: условие; приращение) {

блок

}

Условная часть цикла for вдействительности состоит из трехкомпонентов. Инициализациявыполняетсявсего один раз и определяет начальноезначение управляющей переменной цикла. Условиепроверяетсяв начале каждой итерации и определяет,должна ли выполняться текущая итерация илинет. Наконец, приращениеопределяетизменение управляющей переменной прикаждой итерации. Возможно, термин <приращение>в данном случае неточен, посколькупеременная может как увеличиваться, так иуменьшаться в соответствии с намерениямипрограммиста. Следующий примердемонстрирует простейший случайприменения цикла for:

for($i = 10; $1 <- 100: $1 +=10) : // Обратная косая черта предотвращает

print "\$i = $i <br>"; 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 <br>".$i+=10);

Многие новички не понимают, зачемсоздавать несколько разновидностей цикловв языке программирования, будь то РНР иликакой-нибудь другой язык. Почему нельзяобойтись одной циклической конструкцией?Дело в том, что у цикла for существуетнесколько специфических особенностей.

Например, вы можете инициализироватьнесколько переменных одновременно,разделяя команды инициализации запятыми:

for ($x=0,$y=0: $x+$y<10;$x++) :

$У +=2;                   // Увеличить $у на 2 

print "\$y = $y <BR>";      //Вывести значение $у

$sum = $x + $y;

print "\surn = $sum<BR>";   // Вывести значение $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 <BR>";

}

будет выведен следующий результат:

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_countbottles of $i remaining<BR>";

}

В этом случае результат выглядит так:

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<br>";

case (0.6) :

print "value is 0.6<br>";

break;

case (0.3) :

print "value is 0.3<br>";

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 <br>";

endforeach;

Если значение $magic_number присутствует вмассиве $аrr (как в приведенном примере),поиск прерывается. Результат выглядит так:

val is 14

val is 12

The magic number is in thearray!

Приведенный пример всего лишьдемонстрирует использование команды 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.

Проект: календарь событий

Для практической демонстрации многихконцепций, рассмотренных ранее, я завершаюэту главу описанием программы-календаря. Вкалендаре хранится информация о последнихкулинарных мероприятиях, семинарах подегустации вин и любых других событиях,которые вы сочтете нужным в него включить. Вэтом проекте задействованы многиеконцепции, описанные в этой главе, а такжепредставлен ряд новых концепций, которыебудут рассматриваться в следующих главах.

Информация о событиях хранится в обычномтекстовом файле и выглядит примерно так:

July 21, 2000|8 p. m.|Cooking With Rasmus|PHP creator Rasmus Lerdorfdiscusses the wondersof cheese.

July 23, 2000|11 a. m.|Boxed Lunch|Valerie researches the latest ham sandwichmakingtechniques (documentary)

July 31,2000|2:30p.m.|Progressive Gourmet|Forget the Chardonnay: iced tea isthesophisticated gourmet's beverage of choice.

August 1, 2000|7p.m.|Coder's Critique|Famed Food Critic Brian rates NYC'shottest newInternet cafes.

August 3, 2000|6p.m.|Australian Algorithms|Matt studies the alligator's diet.

На рис. 3.1 изображен результат работысценария РНР, приведенного в листинге 3.1.

Рис. З.1. Примерныйвид календаря

Прежде чем переходить к подробномуанализу кода, потратьте немного времени наизучение алгоритма:

  1. Открыть файл, содержащий информацию особытиях.
  2. Разделить каждую строку на 4 элемента:дату, время, название и краткое описаниемероприятия.
  3. Отформатировать и вывести данные.
  4. Закрыть файл.

Листинг 3.1.Сценарийдля вывода содержимого events.txt в браузере

<?

// Приложение: календарь

// Назначение: чтение и анализ содержимогофайла

// с последующим форматированием длявывода в браузере

// Открыть файловый манипулятор Sevents дляфайла events.txt

$events - fopen ("events.txt". "r");

print "<table border = 0 width = 250>"

print""<tr><td valign=top";

print "<h3>Events Calendar:</h3>";

// Читать, пока не будет найден конец файла

while (! feof(Sevents)) :

// Прочитать следующую строку файла

events.txt$event = fgets($events. 4096);

// Разделить компоненты текущей строки наэлементы массива

$event_info = explode("|". Jevent);

// Отформатировать и вывести информацию особытии

print "$event_info[0] ( $event_info[1] ) <br>";

print "<b>$event_info[2]</b> <br>";

print"$event_info[3] <br> <br>";

endwhile;

// Завершить таблицу

print"</td></tr></table>";

fclose ($events);

?>

Этот короткий пример убедительнодоказывает, что РНР позволяет даженеопытным программистам создаватьреальные приложения с минимальнымиусилиями и затратами времени. Если какие-нибудьиз представленных концепций покажутсянепонятными, не огорчайтесь - на самом делеони очень просты и будут подробно описаны вследующих главах. А если вам не терпитсяузнать побольше об этих вопросах,обратитесь к главе 7 <Файловый ввод/вывод ифайловая система> и главе 8 <Строки ирегулярные выражения> поскольку большаячасть незнакомого синтаксиса описанаименно там.

Итоги

В этой главе были представлены выраженияи управляющие конструкции - средства языкаРНР, которые, вероятно, в той или иной формеприсутствуют практически в любом сценарии.Мы рассмотрели некоторые вопросыиспользования этих средств, а именно:

  • операторы;
  • операнды;
  • приоритет операторов;
  • ассоциативность операторов;
  • управляющие структуры (If, while, do. .while, for,foreach, switch, break, continue).

В первых трех главах книги выпознакомились с базовыми компонентамиязыка РНР. Остальные пять глав первой частирасширяют этот материал; в них вы найдетедополнительную информацию о работе смассивами, объектно-ориентированныхвозможностях, файловом вводе/выводе истроковых операциях РНР. Весь этот материалготовит читателя ко второй части книги,причем особое внимание уделяется средствамРНР, часто используемым при построенииприложений. Итак, держитесь покрепче и несходите с дистанции!