Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

web - tec / PHP 5 для начинающи

.pdf
Скачиваний:
69
Добавлен:
12.06.2015
Размер:
26.79 Mб
Скачать

Логические операторы, циклы и массивы 203

"North Dakota" => "Bismarck", "Ohio" => "Columbus", "Oklahoma" => "Oklahoma City", "Oregon" => "Salem", "Pennsylvania" => "Harrisburg", "Rhode Island" => "Providence", "South Carolina" => "Columbia", "South Dakota" =>"Pierre", "Tennessee" => "Nashville", "Texas" => "Austin", "Utah" => "Salt Lake City", Vermont" => "Montpelier", "Virginia" => "Richmond", "Washington" => "Olympia", "West Virginia" => "Charleston", "Wisconsin" => "Madison", "Wyoming" => "Cheyenne");

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

Итерации в неупорядоченных массивах

Весьма просто реализовать цикл для работы с массивом, элементы которого созда+ вались последовательно (первый элемент был введен первым, второй ++++++ вторым, тре+ тий ++++++ третьим и т.д.). Однако будет ли также просто обрабатывать массив, в котором элементы создавались не по порядку? Например:

$array[56993]="огромное количество"; $array[1]="очень мало"; $array[499]="достаточно много";

На самом деле неупорядоченные массивы не являются сложной проблемой, и все описанные ранее методы также будут работать. PHP ‘‘не обращает внимания’’ на то, что значения сохраняются не по порядку, так как он считает элементы массива распо+ ложенными в прямом числовом порядке индексных значений. Единственная пробле+ ма заключается в том, что при последовательном просмотре всех элементов большого массива (как в примере выше), который содержит только три значения, возможно, придется проверять множество несуществующих элементов.

Функции current() и key()

Для отслеживания элементов при перемещении по массиву в PHP используется ука+ затель. Указатель ссылается на элемент, который используется сценарием в текущий момент времени. Чтобы просмотреть значение данного элемента, можно использо+ вать функцию current(), а для того чтобы определить индекс данного элемента, можно использовать функцию key(). (Ключ (key) ++++++ еще одно название индекса.)

Ниже приведен небольшой фрагмент кода, иллюстрирующий работу функций current() и key(). Неясно, какой индекс PHP будет считать первым при первом просмотре PHP+сценария, содержащего такой код.

$director[4]=" Orson Welles";

$director[1]="Carol Reed";

$director[93]="Fritz Lang";

$director[24]="Jacques Tourneur";

Это можно узнать, добавив несколько строк, которые возвращают текущий индекс массива $director[] и отображают его:

$current_index_value = key($director); echo ($current_index_value);

Функция key() возвращает значение 4. Почему? Потому что она возвращает ин+ декс элемента, который был помещен в массив первым (когда данный сценарий выпол+ няется впервые, первый введенный элемент является текущим элементом), т.е. Orson Welles под индексом 4 (ключ, возвращенный функцией key()). Функция current() вернет значение Orson Welles (значение текущего элемента, найденного функцией current()):

$current_contents = current($director); echo ($current_contents);

204 Глава 4

Теперь, если в массив добавить следующую строку:

$director[]="Alfred Hitchcock";

то строка Alfred Hitchcock будет помещена в массив и получит индекс 94, а не 0, потому что наибольшим значением используемых индексных чисел является 93,

иPHP назначит следующему незаполненному элементу индекс 94. Как можно опреде+ лить, какой индекс будет назначен новому элементу при условии, что функции key()

иcurrent() возвращают информацию по тому элементу, который был помещен в массив первым? Ответ на этот вопрос дан в следующем разделе.

Функции next() и prev()

Для определения индексного значения нового элемента, добавленного в массив, используются функции next() и prev(). Они позволяют перемещаться по массивам, передвигая указатель на следующий или предыдущий элемент соответственно. В качест+ ве аргумента обе функции принимают имя массива. Например, для созданного в пре+ дыдущем примере массива:

$director[4]="Orson Welles";

$director[1]="Carol Reed";

$director[93]="Fritz Lang";

$director[24]="Jacques Tourneur";

$director[]="Alfred Hitchcock";

можно вызвать функцию next() до проверки текущего индекса и содержимого текущего элемента:

next($director);

$current_index_value = key($director); echo ($current_index_value);

В результате этого будет отображено значение 1, а функция current() вернет строку Carol Reed.

Если вызвать функцию next() еще три раза

next($director); next($director); next($director); next($director);

$current_index_value = key($director); echo ($current_index_value);

будет выведено значение 94. Если теперь вызвать функцию current():

$current_contents = current($director); echo ($current_contents);

то в браузере будет выведена строка ‘‘Alfred Hitchcock’’.

Функция prev() используется аналогично. Возьмем предыдущий пример и доба+ вим вызов prev() после четырех вызовов next():

next($director); next($director); next($director); next($director); prev($director);

$current_index_value = key($director); echo ($current_index_value);

Ввиду того, что указатель был передвинут вперед на четыре элемента и на один на+ зад, будет выведено число 24, которое является индексным значением, связанным со строкой Jacques Tourneur. Это довольно просто, хотя возникает один вопрос: что

Логические операторы, циклы и массивы 205

случится, если вызов next() передвинет указатель за последний элемент массива или prev() установит указатель перед первым элементом?

prev($director);

$current_index_value = key($director); echo ($current_index_value);

Ничего особенного не произойдет. Код не вернет никакого значения и не сгене+ рирует ошибку (как это было бы в некоторых языках программирования); указатель просто выходит за границу массива, но его можно вернуть обратно:

prev($director); next($director); next($director);

$current_index_value = key($director); echo ($current_index_value);

В данном случае также не будет никакого вывода.

Итак, очевидно, что порядок, в котором наполняется массив, никак не влияет на порядок перемещения по элементам массива. Любое новое значение, добавленное в массив, помещается в элемент, который следует сразу за существующим элементом, имеющим наибольший индекс. Поэтому если наивысший индекс заполненного эле+ мента равен 34, то следующее значение будет вставлено в массив с индексом 35.

Следует запомнить, что для перемещения по массиву используются функции next() и prev(), а для отображения текущей позиции (элемента, на который в текущий мо+ мент времени ссылается указатель) используются функции current() и key().

Функции list() и each()

Можно упростить перемещение в неупорядоченных массивах. Вместо того чтобы обрабатывать в цикле множество пустых значений, можно использовать функции list() и each(), и возвращать только те элементы массива, которые содержат дан+ ные. Это позволяет с минимальными усилиями отображать все содержимое массива. Для этого используется цикл while:

while (list(IndexValue,ElementContents) = each(ArrayName))

Это означает: для каждого элемента массива ArrayName установить значение IndexValue равным индексу элемента, а значение ElementContents равным содержимому данного элемента. Если требуется возвращать либо индекс, либо значение, то лишний атрибут можно просто опустить:

while (list(IndexValue) = each(ArrayName))

или

while (list(,ElementContents) = each(ArrayName))

Для отображения имени каждого режиссера можно написать следующий код:

while (list($element_index_value, $element_contents) = each($director)){ echo "<br>$element_index_value - $element_contents";

}

Называть переменные именами $element_index_value и $element_contents

необязательно; это сделано просто для ясности. Их можно было бы назвать по+другому:

while (list($MickeyMouse, $DonaldDuck) = each ($Director)){ echo "<BR>$MickeyMouse - $DonaldDuck";

}

206 Глава 4

В любом случае результат будет следующим:

4 - Orson Welles

1 - Carol Reed

93 - Fritz Lang

24 - Jacques Tourneur

94 - Alfred Hitchcock

Необходимо помнить только то, что функция list() возвращает сначала индекс, а затем содержимое элемента. Это предоставляет программисту некоторые полезные средства, которые применимы даже тогда, когда массив не имеет числовых индексов.

Итерации в ассоциативных массивах

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

$state_capital["GA"]="Atlanta"; $state_capital["IL"]="Springfield"; $state_capital["CA"]="Sacramento"; $state_capital[] = "Cheyenne";

Значение Cheyenne будет сохранено в элементе $state_capital[0]. Это не уди+ вительно, учитывая, что PHP ‘‘не знает’’, какие индексные значения намерен исполь+ зовать программист; это может быть WY или AB, или 4563, поэтому PHP пытается най+ ти наибольший числовой индекс. Поскольку при создании массива числовые индексы не добавлялись, PHP начинает с нуля.

Функции current() и key() будут работать так, как и предполагается для ассо+ циативных массивов. Следующий код

$what_state = current($state_capital); $what_abbreviation = key($state_capital); echo "$what_abbreviation - $what_state";

вернет первый элемент массива, т.е. элемент с индексом GA, содержащий значение Atlanta. Можно перемещаться по элементам массива, как и раньше:

$state_capital["GA"]="Atlanta"; $state_capital["IL"]="Springfield"; $state_capital["CA"]="Sacramento"; $state_capital[] = "Cheyenne"; next($$state_capital);

$what_state = current($state_capital); $what_abbreviation = key($state_capital); echo "$what_abbreviation - $what_state";

На этот раз отображается результат IL - Springfield. Функции list() и each() тоже работают. Можно создать следующий массив:

$state_capital = array ("GA" => "Atlanta", "IL" => "Springfield", "CA" => "Sacramento", "WY" => "Cheyenne");

А затем передавать данный массив функции each и использовать list() для ото+ бражения содержимого элементов:

while (list($state_abbreviation, $state_name) = each ($state_capital)){ echo "<br>$state_abbreviation - $state_name";

}

При этом, как и ожидалось, создается список аббревиатур и названий штатов, а за+ тем они отображаются в том порядке, в котором были созданы:

Логические операторы, циклы и массивы 207

GA - Atlanta

IL - Springfield

CA - Sacramento

WY - Cheyenne

Как заставить PHP создать или сохранить другой порядок? Читайте об этом в сле+ дующем разделе.

Сортировка массивов

В PHP имеется несколько функций для сортировки массивов. В данном разделе рассматриваются пять наиболее широко используемых функций: sort(), asort(), rsort(), arsort() и ksort(). Все они работают совместно с уже рассмотренными функциями list() и each().

Функция sort()

sort() ++++++ основная функция сортировки. Она принимает элементы массива и сортирует их в алфавитном порядке. Функции требуется передать только имя сор+ тируемого массива:

sort(ArrayName)

Если массив режиссеров создается с помощью функции array():

$director = array ("Orson Welles","Carol Reed","Fritz Lang","Jacques Tourneur");

то можно отсортировать элементы, передав функции sort() имя данного массива:

sort($director);

Чтобы понять, как данная функция влияет на массив, можно снова использовать функции list() и each(). Как уже отмечалось, в массиве элементы хранятся в том порядке, в котором они были созданы. В данном массиве ожидается следующий поря+ док элементов:

$director[0]= "Orson Welles"

$director[1]= "Carol Reed"

$director[2]= "Fritz Lang"

$director[3]= "Jacques Tourneur"

Однако после использования функции sort() порядок будет другим, так как функция расположила значения элементов в алфавитном порядке, а затем пере+ строила индексные номера так, чтобы они соответствовали новому порядку:

$director[0]= "Carol Reed"

$director[1]= "Fritz Lang"

$director[2]= "Jacques Tourneur"

$director[3]= "Orson Welles"

Это можно проверить, воспользовавшись ранее созданным фрагментом кода, ко+ торый отображает на экране содержимое списка:

while (list($IndexValue, $DirectorName) = each ($director)){ echo "<BR>$IndexValue - $DirectorName";

}

Функция asort()

Функция asort() принимает массивы со строковыми индексами и сортирует их согласно значениям элементов. Это не совсем то же самое, что делает функция sort. asort() ++++++ оставляет индексные номера или имена элементов нетронутыми, а не пе+ рестраивает их, как функция sort. Обратимся снова к массиву столиц штатов:

208 Глава 4

$state_capital = array ("GA" => "Atlanta", "IL" => "Springfield", "CA" => "Sacramento", "WY" => "Cheyenne");

Массив создается так же, как и при использовании следующего кода:

$state_capital["GA"]= "Atlanta" $state_capital["IL"]= "Springfield" $state_capital["CA"]= "Sacramento" $state_capital["WY"]= "Cheyenne"

Вызовем для данного массива функцию sort():

sort($state_capital);

В результате этого образуется следующий порядок:

$state_capital[0]= "Atlanta" $state_capital[1]= "Cheyenne"

$state_capital[2]= "Sacramento" $state_capital[3]= "Springfield"

Иными словами, строковые индексы были заменены числовыми индексами, что не очень полезно. Но если вместо этого вызывать функцию asort():

asort($state_capital);

то порядок будет таким:

$state_capital["GA"]= "Atlanta" $state_capital["WY"]= "Cheyenne" $state_capital["IL"]= "Sacramento" $state_capital["CA"]= "Springfield"

На этот раз элементы были отсортированы в алфавитном порядке, а строковые индексы остались. Чтобы убедиться, что это действительно так, можно снова исполь+ зовать функции list() и each():

while (list($state_abbreviation, $state_name) = each ($state_capital)){ echo "<br>$state_abbreviation - $state_name";

}

Функции rsort() и arsort()

Функции rsort() и arsort() работают аналогично своим близким родственникам sort() и asort(). Единственным отличием является то, что они возвращают элемен+ ты в обратном алфавитном порядке. Для того чтобы отсортировать список режиссеров в обратном алфавитном порядке, можно использовать функцию rsort():

$director = array ("Orson Welles","Carol Reed","Fritz Lang","Jacques Tourneur");

rsort($director);

Для сортировки списка столиц штатов можно использовать функцию arsort():

$state_capital = array ("ga" => "Atlanta", "il" => "Springfield", "ca" => "Sacramento", "wy" => "Cheyenne");

arsort($state_capital);

Результаты должны быть очевидны. Чтобы проверить их, можно адаптировать код для отображения результатов из предыдущих разделов. Данные функции полезны, ес+ ли требуется отсортировать элементы по убыванию, а не по возрастанию.

Логические операторы, циклы и массивы 209

Функция ksort()

Функция ksort() сортирует содержимое ассоциативного массива по индексам. Она применяется точно так же, как другие функции сортировки, но упорядочивает ассоциативный массив в алфавитном порядке строковых индексов. Эта функция по+ лезна для сортировки по индексным номерам или именам элементов, когда необхо+ димо манипулировать данными по именам элементов, а не по значениям. Например, в случае списка столиц штатов:

$state_capital = array ("ga" => "Atlanta", "il" => "Springfield", "ca" => "Sacramento", "wy" => "Cheyenne");

ksort($state_capital);

функция ksort() создаст следующий порядок:

$state_capital["ca"]= "Sacramento" $state_capital["ga"]= "Atlanta" $state_capital["il"]= "Springfield" $state_capital["wy"]= "Cheyenne"

Поэтому если для каких+либо целей понадобится использовать аббревиатуры шта+ тов, а не их названия, то их также можно отсортировать.

Многомерные массивы

PHP позволяет создавать массивы массивов. Такие структуры получили название многомерных массивов. Они полезны для представления данных, которые требуют двух наборов индексов, например, координат на карте. В принципе, существует воз+ можность создавать вложенные массивы в многомерном массиве до тех пор, пока PHP будет хватать памяти. Вероятно, этот предел наступает в районе 100 вложенных мас+ сивов (тот, кто сможет предложить целесообразное практическое применение для массивов с более чем 10 вложенными массивами, заслуживает особой награды). Мно+ гомерные массивы создаются так же, как и обычные массивы, за исключением того, что конструкция array вызывается как аргумент для самой себя:

ArrayName = array (index => array (элементы массива))

В качестве примера можно описать массив, в котором каждый элемент представ+ ляет одного члена какой+либо группы людей и одновременно является массивом, со+ держащим некоторые сведения об этом человеке:

$phone_directory = array ("John Doe" => array ("1 Long Firs Drive", "777-000-000"), "Jane Doe" => array ("4 8th and East","777-111-111"));

В данном массиве содержатся элементы John Doe и Jane Doe; и каждый из этих элементов в свою очередь представляет массив с двумя элементами: адресом и номе+ ром телефона. Чтобы распечатать данную информацию, необходимо использовать вложенный цикл:

$phone_directory = array ("John Doe" => array("1 Long Firs Drive", "777-000-000"),

"Jane Doe" => array("4 8th and East","777-111-111")); while (list($person) = each($phone_directory)){

echo("<br>$person");

while (list(,$personal_details) = each ($phone_directory[$person])) { echo (" $personal_details");

}

}

Тег <br> и пробел перед $personal_details в операторе echo используются просто для того, чтобы сделать вывод информации удобочитаемым. Многомерные массивы встречаются не очень часто, поэтому здесь они не описываются.

210 Глава 4

Практическое использование массивов

Материал данной главы проиллюстрирован на кратком примере, который вклю+ чает многие из рассмотренных функций.

Практика Комбинированное использование функций для работы с массивами

В следующем примере группе вымышленных студентов предлагается ответить на вопросы об оценках, которые они получили на экзамене по математике. Кроме все+ го прочего на Web+странице имена студентов будут отсортированы в порядке полу+ ченных студентами оценок (A ++++++ самая высокая оценка, F ++++++ самая низкая). Чтобы представить результаты в более читабельном виде, используется несколько HTML+ таблиц (теги <table>).

1. Запустите редактор Web+страниц и введите следующий код:

<html>

<head><title></title></head>

<body>

<form method="POST" action="exam.php">

<input type="hidden" name="posted" value="true"> <table border="1">

<?php

$student = array("Альберт Эйнштейн","Иван Грозный","Наполеон","Саймон Боливар","Исаак Ньютон");

while (list(,$name) = each($student))

{

echo "<tr><td>Какую оценку по математике получил <b>$name</b>?</td>"; echo"<td><select name='math[]'>

<option>A</option>

<option>B</option>

<option>C</option>

<option>D</option>

<option>F</option>

</select>";

echo"<input type='hidden' name='student[]' value='$name'></td>";

}

?>

</tr>

<tr><td> </td><td>

<input type="submit" value="Показать оценки"> </td></tr>

</form>

</table>

<?php

if (isset($_POST['posted'])) { ?>

<hr>

<table border="1">

<tr><td colspan="2">

Оценки по математике расположены в следующем порядке: </td></tr>

<?php

while (list($index,$value)=each($_POST['math']))

{

$gradestudent[]=$_POST['math'][$index].$_POST['student'][$index];

}

Логические операторы, циклы и массивы 211

asort($gradestudent);

while (list($index,$value)=each($gradestudent))

{

$student_index = $_POST['student'][$index]; $math_index = $_POST['math'][$index];

echo "<tr><td><b>$student_index</b></td><td>$math_index</td></tr>";

}

}

?>

</table>

</body>

</html>

2.Сохраните данный файл как exam.php и закройте его.

3.Откройте созданный файл в браузере и введите несколько оценок (пример на рис. 4.12).

Рис. 4.12.

4.Нажмите кнопку Показать оценки и данные будут отсортированы не только по оценкам, но и в алфавитном порядке имен студентов, если несколько студентов получили одинаковые оценки (рис. 4.13).

212 Глава 4

Рис. 4.13.

Как это работает

Представленная программа решает сложную задачу по сортировке полученных дан+ ных. Необходимо отсортировать массив оценок, которые согласованы по индексу с мас+ сивом студентов. Однако как можно связать отсортированный массив оценок с масси+ вом студентов? Сделать это без особых сложностей позволяет один технический прием.

Программа создает динамическую форму, которая выводит имена студентов из массива $student:

<form method="POST" action="exam.php">

<input type="hidden" name="posted" value="true"> <table border="1">

<?php

$student = array("Альберт Эйнштейн","Иван Грозный","Наполеон","Саймон Боливар","Исаак Ньютон");

Цикл while обрабатывает элементы данного массива. Понадобятся только имена сту+ дентов, а не их индексы, поэтому функции list() передается только второй параметр:

while (list(,$name) = each($student))

{

Для всех студентов в списке отображаются запросы оценок:

echo "<tr><td>Какую оценку по математике получил <b>$name</b>?</td>";

Соседние файлы в папке web - tec