Глава 5. Массивы
ГЛАВА 5
Массивы
В главе 2 были представлены две разновидности массивов, используемых в
программах РНР, — индексируемые и ассоциативные. Вероятно, вы помните, что
в индексируемых массивах при обращении к элементу указывается его позиция,
а в ассоциативных массивах для этой цели используется специальный ключ.
Обе разновидности массивов обладают гибкими и мощными средствами для
работы с большими объемами данных
В этой главе рассматриваются различные средства РНР по работе с
массивами. К концу этой главы вы познакомитесь с одномерными и
многомерными массивами, сортировкой и перебором элементов, а также с
другими возможностями, часто используемыми при работе с массивами. Книгу
не стоит рассматривать как подробный справочник по всем существующим
функциям, хотя так уж получилось, что в этой главе рассматриваются
практически все функции массивов. Последнюю версию списка функций можно
найти на домашней странице РНР по адресу http://www.php.net/ .
Массив представляет собой совокупность объектов, имеющих одинаковые
размер и тип. Каждый объект в массиве называется элементом массива.
Создать новый массив в РНР несложно. При объявлении индексируемого массива
после имени переменной ставится пара квадратных скобок ([ ]):
$languages [ ] = "Spanish";
// $languages[0] = "Spanish"
После этого в массив можно добавлять новые элементы, как показано ниже.
Обратите внимание: новые элементы добавляются без явного указания индекса.
В этом случае новый элемент добавляется в позицию, равную длине массива
плюс 1:
$languages[ ] = "English"; // $1anguages[l] = "English";
$languagest ] = "Gaelic"; // $languages[2] = "Gaelic";
Кроме того, новые элементы можно добавлять в конкретную позицию
массива. Для этого указывается индекс нрвого элемента:
$languages[15] = "Italian";
$languages[22] = "French";
Ассоциативные массивы создаются аналогичным образом:
$languages["Spain"] = "Spanish";
$languages["France"] = "French";
При создании массивов используются три стандартные языковые
конструкции:
- аrrау( );
- list( );
- range( ).
Хотя все три случая приводят к одному результату — созданию массива, в
некоторых случаях одна конструкция может оказаться предпочтительнее
других. Далее приведены описания и примеры использования каждой
конструкции.
аггау( )
Функция array( ) получает ноль или более элементов и возвращает массив,
состоящий из указанных элементов. Ее синтаксис:
array array ( [элемент1, элемент2...] )
Вероятно, array( ) является всего лишь более наглядной записью для
создания массива, используемой для удобства программиста. Ниже показан
пример использования array( ) для создания индексируемого массива:
$languages = array ("English". "Gaelic". "Spanish");
// $languages[0] = "English". $languages[1] = "Gaelic",
// $languages[2] = "Spanish"
А вот как array( ) используется при создании ассоциативных
массивов:
$languages = array("Spain" => "Spanish",
"Ireland" => "Gaelic".
"United States" => "English");
// $languages["Spain"] = "Spanish"
// $languages["Ireland"] = "Gaelic"
// $languages["United States"] = "English"
Ассоциативные массивы особенно удобны в тех ситуациях, когда числовые
индексы не имеют логического соответствия. Например, в предыдущем примере
названия стран вполне естественно ассоциируются с языками. Попробуйте-ка
воплотить эту логическую связь при помощи цифр!
list( )
Конструкция list( ) похожа на аrrау( ), однако ее главная задача —
одновременное присваивание значений, извлеченных из массива, сразу
нескольким переменным. Синтаксис команды list( ):
void list (переменная1 [. переменная2 , ...] )
Конструкция list() особенно удобна при чтении информации из базы данных
или файла. Допустим, вы хотите отформатировать и вывести данные,
прочитанные из текстового файла. Каждая строка файла содержит сведения о
пользователе (имя,
профессия и любимый цвет); компоненты записи разделяются вертикальной
чертой (|). Типичная строка выглядит так:
Nino Sanzi|Professional Golfer|green
При помощи list ( ) можно написать простой цикл, который будет читать
каждую строку, присваивать ее компоненты переменным, форматировать и
отображать данные. Приведенный ниже листинг демонстрирует возможность
одновременного присваивания нескольким переменным с использованием list (
):
// Читать строки, пока не будет достигнут конец файла
while ($line = fgets ($user_file. 4096)) :
// Разделить строку функцией split( ).
// Компоненты присваиваются переменным Sname. $occupation и Scolor.
list ($name, $occupation, $color) = split( "|", $line);
// Отформатировать и вывести данные
print "Name: Sname <br>";
print "Occupation: Soccupation <br>";
print "Favorite color: Scolor <br>";
endwhile;
Каждая строка файла читается, форматируется и выводится в следующем
виде:
Name: Nino Sanzi
Occupation: Professional Golfer
Favorite color: green
В приведенном примере применение list( ) зависит от разделения строки
на элементы функцией split( ). Элементы, полученные в результате деления,
присваиваются, соответственно, переменным $name, $occupation и $color.
Дальше все сводится к форматированию данных для вывода в конкретном
браузере. Удобные средства лексического анализа текстовых файлов являются
одной из сильных сторон РНР. Эта тема подробно рассматривается в главах 7
и 8.
range ( )
Конструкция range( ) позволяет легко и быстро создать массив целых
чисел из интервала, определяемого верхней и нижней границами. Range( )
возвращает массив, состоящий из всех целых чисел указанного интервала.
Синтаксис range( ):
array range (int нижняя_граница, int верхняя граница)
Следующий пример наглядно показывает, насколько удобна эта
конструкция:
$lottery = range(0,9);
// $lottery = array(0,1,2,3,4,5,6,7,8,9)
Как видно из приведенного фрагмента, в параметрах range( ) был указан
интервал от 0 до 9 и массив $lottery был заполнен целыми числами из этого
интервала.
Многомерные массивы
Со временем ваши программы станут более сложными, и возможностей
простых одномерных массивов окажется недостаточно для хранения необходимой
информации. Многомерный массив (массив массивов) предоставляет в
распоряжение программиста более эффективные средства для хранения
информации, требующей дополнительного структурирования. Создать
многомерный массив несложно — просто добавьте дополнительную пару
квадратных скобок, чтобы вывести массив в новое измерение:
$chessboard [1] [4] = "King"; // Двухмерный массив
$capitals["USA"] ["Ohio"] = "Columbus": // Двухмерный массив
$streets["USA"]["Ohio"]["Columbus"] = "Harrison"; // Трехмерный
массив
В качестве примера рассмотрим массив, в котором хранится информация о
десертах и особенностях их приготовления. Обойтись одномерным массивом
было бы довольно трудно, но двухмерный массив подходит как нельзя
лучше:
$desserts = аrrау(
"Fruit Cup" => array (
"calories" => "low",
"served" -> "cold",
"preparation" => "10 minutes"
),
"Brownies" => array (
"calories" -> "high",
"served" => "piping hot",
"preparation" => "45 minutes"
)
);
После создания массива к его элементам можно обращаться по
соответствующим ключам:
$desserts["Fruit Cup"]["preparation"] // возвращает "10 minutes"
$desserts["Brownies"]["calories"] // возвращает "high"
Присваивание значений элементам многомерных массивов выполняется так
же, как и в одномерных массивах:
$desserts["Cake"]["calories"] = "too many";
// Присваивает свойству "calories" объекта "Cake" значение "too
many"
Хотя в многомерных массивах появляются новые уровни логической
организации данных, многомерные массивы создаются практически так же, как
и одномерные. Впрочем, ссылки на многомерные массивы в строках требуют
особого внимания; этой теме посвящен следующий раздел.
Ссылки на многомерные массивы
Ссылки на элементы многомерных массивов внутри строк несколько
отличаются от ссылок на другие типы данных. Возможны два варианта.
Во-первых, можно воспользоваться оператором конкатенации:
print "Brownies are good, but the calories content is ".
$desserts["Brownies"]["calories"];
Во-вторых, ссылку на элемент многомерного массива можно заключить в
фигурные скобки ({ }):
print "Brownies are good, but the calories content is
{$desserts[Brownies][calories]}";
Обратите внимание на отсутствие кавычек вокруг ключей. Также следует
помнить, что между фигурными скобками и ссылкой не должно быть лишних
пробелов. Если хотя бы одно из этих условий не выполняется, произойдет
ошибка. Впрочем, годятся оба способа. Я рекомендую выбрать один формат и
придерживаться его, чтобы ваши программы выглядели более последовательно.
Если не использовать какой-либо из этих способов форматирования, ссылки на
многомерные массивы будут интерпретироваться буквально, что наверняка
приведет к непредвиденным результатам.
Поиск элементов массива
Поиск элементов относится к числу важнейших операций с массивами. В РНР
существует несколько стандартных функций, позволяющих легко находить в
массиве нужные ключи и значения.
in_array( )
Функция i n_array ( ) проверяет, присутствует ли в массиве заданный
элемент. Если поиск окажется удачным, функция возвращает TRUE, в противном
случае возвращается FALSE. Синтаксис функции in_array( ):
bool in_array(mixed элемент, array массив)
Эта функция особенно удобна тем, что вам не приходится в цикле
перебирать весь массив в поисках нужного элемента. В следующем примере
функция in_array( ) ищет элемент "Russian" в массиве $languages:
$languages = array("English", "Gaelic", "Spanish"):
$exists = in_array("Russian", $languages); // $exists присваивается
FALSE
$exists = in_array("English", $languages): // $exists присваивается
TRUE
Функция in_array( ) часто встречается в управляющих конструкциях, когда
ее возвращаемое значение (TRUE/FALSE) используется для выбора одного из
двух вариантов продолжения. В следующем примере функция in_array( )
используется для выбора одного из двух вариантов в условной команде
if:
// Ввод данных пользователем
$language = "French"; $email = "wjgilmore@hotmail.com";
// Если язык присутствует в массиве
if (in_array($language. $languages)) :
// Подписать пользователя на бюллетень.
// Обратите внимание: в РНР нет стандартной функции с именем
// subscribe_user(). В данном примере эта функция просто имитирует
// процесс подписки.
subscribe_user($email, $language);
print "You are now subscribed to the $language edition of the
newsletter.";
// Язык отсутствует в массиве
else :
print "We're sorry, but we don't yet offer a $language edition of the
newsletter".
endif;
Что происходит в этом примере? Допустим, переменные $language и $email
содержат данные, введенные пользователем. Вы хотите убедиться в том, что
указанный язык поддерживается вашей системой, и используете для этой цели
функцию in_array( ). Если название языка присутствует в массиве,
пользователь подписывается на бюллетень и получает соответствующее
сообщение. В противном случае программа сообщает, что на указанном языке
бюллетень не распространяется. Конечно, в настоящей программе пользователь
не должен гадать, какие языки поддерживаются вашей программой. Задача
решается при помощи раскрывающегося списка — эта тема подробно
рассматривается в главе 10. Здесь этот пример всего лишь демонстрирует
возможности работы с массивами.
array_keys( )
Функция array_keys( ) возвращает массив, содержащий все ключи исходного
массива, переданного в качестве параметра. Если при вызове передается
дополнительный параметр искомый_элемент, возвращаются только ключи,
которым соответствует заданное значение; в противном случае возвращаются
все ключи массива. Синтаксис функции array_keys( ):
array array_keys (array массив [, mixed искомый_элемент])
Рассмотрим пример использования функции array_keys( ) для получения
ключа заданного элемента:
$great_wines = array ("Australia" => "Clarendon Hills 96",
"France" => "Comte George de Vogue 97",
"Austria" => "Feiler Artinger 97");
$great_labels = array_keys($great_wines);
// $great_labels = array("Australia", "France", "Austria");
$great_labels = array_keys($great_wines, "Clarendon Hills 96");
// $great_labels = array("Australia");
Функция array_keys( ) позволяет очень легко получить все ключи
ассоциативного массива — например, в предыдущем случае ими были названия
стран, в которых производятся различные сорта вин.
array_values( )
Функция array_values( ) возвращает массив, состоящий из всех значений
исходного массива, переданного в качестве параметра. Синтаксис функции
array_values( ):
array array_values(array массив)
Вернемся к предыдущему примеру, в котором функция array_keys( )
использовалась для получения всех значений ключей. На этот раз функция
array_values( ) возвращает все значения, соответствующие ключам:
// $great_wines = array ("Australia" => "Clarendon Hills 96",
// "France" => "Comte George de Vogue 97",
// "Austria" => "Feiler Artinger 97");
$great_labels = array_values($great_wines);
// $great_labels = аrrау("Clarendon Hills 96",
// "Comte George de Vogue 97",
// "Feiler Artinger 97");
Функции array_keys( ) и array_values( ) дополняют друг друга, позволяя
при необходимости получить все составляющие той или иной стороны
ассоциативного массива.
Добавление и удаление элементов
К счастью, в РНР при создании массива не нужно указывать максимальное
количество элементов. Это увеличивает свободу действий при операциях с
массивами, поскольку вам не приходится беспокоиться о случайном выходе за
границы массива, если количество элементов превысит ожидаемый порог. В РНР
существует несколько функций для увеличения размеров массива. Некоторые из
них были созданы для удобства программистов, привыкших работать с
различными типами очередей и стеков (FIFO, FILO и т. д.), что отражается в
названиях функций (push, pop, shift и unshift). Но даже если вы не знаете,
что такое «очередь» или «стек», не огорчайтесь — в этих функциях нет
ничего сложного.
Очередью (queue) называется структура данных, из которой элементы
извлекаются в порядке поступления. Стеком (stack) называется структура
данных, из которой элементы извлекаются в порядке, обратном порядку их
поступления.
array_push( )
Функция array_push( ) присоединяет (то есть дописывает в конец массива)
один или несколько новых элементов. Синтаксис функции array_push( ):
int array_push(array массив, mixed элемент [, ...])
Длина массива возрастает прямо пропорционально количеству его
элементов. Это продемонстрировано в следующем примере:
$languages = array("Spanish", "English", "French");
array_push($languages, "Russian", "German", "Gaelic");
// $languages = array("Spanish", "English", "French",
// "Russian", "German", "Gaelic")
У функции array_push( ), как и у многих стандартных функций РНР,
существует «двойник» — функция аrrау_рор( ), предназначенная для
извлечения элементов из массива. Главное различие между этими функциями
заключается в том, что array_push( ) может добавлять несколько элементов
одновременно, а аrrау_рор( ) удаляет элементы только по одному.
аrrау_рор( )
Результат работы функции аrrау_рор( ) прямо противоположен array_push(
) — эта функция извлекает (то есть удаляет) последний элемент из массива.
Извлеченный элемент возвращается функцией. Синтаксис функции аrrау_рор(
):
аrrау_рор(аrrау массив)
При каждом выполнении аrrау_рор( ) размер массива уменьшается на 1.
Рассмотрим пример:
$languages = array("Spanish", "English", "French",
"Russian", "German", "Gaelic");
$a_language = array_pop($languages): // $a_language = "Gaelic"
$a_language = array_pop($languages): // $a_language = "German"
// $languages = array ("Spanish", "English", "French", "Russian");
Функции array_push( ), и array_pop( ) удобны тем, что с их помощью
можно выполнять операции с элементами и управлять размером массива, не
беспокоясь о неинициализированных или пустых элементах. Такое решение
работает намного эффективнее, чем любые попытки управления этими факторами
со стороны программиста.
array_shift( )
Функция array_shift( ) аналогична аrrау_рор( ) с одним отличием:
элемент удаляется из начала (левого края) массива. Все остальные элементы
массива сдвигаются на одну позицию к началу массива. У функции
array_shift( ) такой же синтаксис, как и у аггау_рор( ):
array_shift(array массив)
При работе с функцией array_shift( ) необходимо помнить, что элементы
удаляются из начала массива, как показывает следующий пример:
$languages = array("Spanish", "English", "French", "Russian");
$a_language = array_shift($languages); // $a_language = "Spanish";
// $languages = array("English", "French", "Russian");
array_unshift( )
Функция array_unshift( ) дополняет array_shift( ) — новый элемент
вставляется в начало массива, а остальные элементы сдвигаются на одну
позицию вправо. Синтаксис команды array_unshift( ):
1nt array_unshift(array массив, mixed переменная1 [....переменная2])
При одном вызове функции можно добавить как один, так и несколько
элементов, при этом размер массива возрастает пропорционально количеству
добавленных элементов. Пример добавления нескольких элементов:
$languages = array("French", "Italian", "Spanish");
array_unshift($languages, "Russian", "Swahili", "Chinese");
// $languages = array("Russian", "Swahili", "Chinese",
// "French", "Italian", "Spanish");
array_pad( )
Функция array_pad( ) позволяет быстро увеличить массив до желаемого
размера посредством его дополнения стандартными элементами. Синтаксис
функции array_pad( ):
array arrap_pad(array массив, int размер, mixed значение):
Параметр размер определяет новую длину массива. Параметр значение
задает стандартное значение, присваиваемое элементам во всех новых
позициях массива. При использовании array_pad( ) необходимо учитывать
некоторые обстоятельства:
Если размер положителен, массив дополняется справа, а если отрицателен
— слева.
Если абсолютное значение параметра размер меньше либо равно длине
массива, никаких действий не выполняется.
Абсолютным значением (модулем) целого числа называется его значение без
знака. Например, абсолютное значение чисел 5 и -5 равно 5.
Пример дополнения массива с конца:
$weights = array(1, 3, 5, 10, 15, 25, 50);
$weights = array_pad($weights. 10, 100);
// Результат: $weights = array(1, 3, 5, 10, 15, 25, 50, 100, 100,
100);
Пример дополнения массива с начала:
$weights = array(1, 3, 5, 10, 15, 25, 50);
$weights = array_pad($weights, -10, 100);
// Результат: $weights = array(100, 100, 100, 1, 3, 5, 10, 15, 25,
50);
Неправильная попытка дополнения массива:
$weights = array(1, 3, 5, 10, 15, 25, 50);
$weights = array_pad($weigtits, 3, 100);
// Массив $weights не изменяется:
// $weights = array(1, 3, 5, 10, 15, 25, 50);
Перебор элементов
В РНР существует несколько стандартных функций, предназначенных для
перебора элементов массива. В совокупности эти функции обеспечивают гибкие
и удобные средства для быстрой обработки и вывода содержимого массивов.
Вероятно, вы будете часто использовать эти функции, поскольку они лежат в
основе практически всех алгоритмов работы с массивами.
reset( )
Функция reset( ) переводит внутренний указатель текущей позиции в
массиве к первому элементу. Кроме того, она возвращает значение первого
элемента. Синтаксис функции reset( ):
mixed reset (array массив)
Рассмотрим следующий массив:
$fruits = array("apple", "orange", "banana");
Допустим, указатель текущей позиции в этом массиве установлен на
элемент "orange". Команда:
$a_fruit = reset($fruits);
вернет указатель в начало массива, то есть на элемент "apple", и вернет
это значение, если результат вызова reset( ) используется в программе.
Возможен и упрощенный вариант вызова:
reset($fruits);
В этом случае указатель переходит к первому элементу массива, а
возвращаемое значение не используется.
each ( )
Функция each( ) при каждом вызове выполняет две операции: она
возвращает пару «ключ/значение», на которую ссылается указатель текущей
позиции, и перемещает указатель к следующему элементу. Синтаксис функции
each( ):
array each (array массив)
Для удобства each ( ) возвращает ключ и значение в виде массива из
четырех элементов; ключами этого массива являются 0, 1, value и key.
Возвращаемый ключ ассоциируется с ключами 0 и key, а возвращаемое значение
— с ключами 1 и value.
В следующем примере функция each ( ) возвращает элемент, находящийся в
текущей позиции:
// Объявить массив из пяти элементов
$spices = array("parsley", "sage", "rosemary", "thyme", "pepper");
// Установить указатель на первый элемент массива
reset($spices);
// Создать массив $a_sp1ce. состоящий из четырех элементов
$a_spice = each($spices);
В результате выполнения приведенного фрагмента массив $a_spice будет
содержать следующие пары «ключ/значение»:
- 0 => 0;
- 1 => "parsley";
- key => 0;
- value => "parsley".
После этого строку "parsley" можно вывести любой из следующих
команд:
print $a_spice[1]: print $a_spice["value"];
Функция each() обычно используется в сочетании с list( ) в циклических
конструкциях для перебора всех или некоторых элементов массива. При каждой
итерации each( ) возвращает либо следующую пару «ключ/значение», либо
логическую ложь при достижении последнего элемента массива. Вернемся к
массиву $spices; чтобы вывести все элементы на экран, можно
воспользоваться следующим сценарием:
// Сбросить указатель текущей позиции
reset($spices);
// Перебрать пары "ключ/значение", ограничиваясь выводом значения
while (list ($key, $val) = each ($spices) ) :
print "$val <br>"
endwhile;
Ниже приведен более интересный пример использования each( ) в сочетании
с другими функциями, описанными в этой главе. Листинг 5.1 показывает, как
при помощи этих функций вывести отформатированную таблицу стран и
языков.
Листинг 5.1. Построение таблицы HTML по содержимому массива
// Объявить ассоциативный массив стран и языков $languages = array
("Country" => "Language",
"Spain" => "Spanish",
"USA" => "English",
"France" => "French",
"Russia" => "Russian");
// Начать новую таблицу
print "<table border=l>";
// Переместить указатель к позиции первого элемента
reset ($languages);
// Прочитать первый ключ и элемент
$hdl = key ($languages);
Shd2 = $languages[$hd1];
// Вывести первый ключ и элемент в виде заголовков таблицы
print
"<tr><th>$hd1</th><th>$hd2</th></tr>";
next($languages);
// Выводить строки таблицы с ключами и элементами массива
while (list ($ctry,$lang) = each ($languages)) :
print
"<tr><td>Sctry</td><td>$lang</td></tr>";
endwhile;
// Завершить таблицу print "</table>";
?>
В результате выполнения этого кода будет построена следующая таблица
HTML.
Country |
Language |
Spain |
Spanish |
USA |
English |
France |
French |
Russia |
Russian
|
Этот пример дает представление о самой сильной стороне РНР —
возможности объединения динамического кода с HTML для получения
наглядного, отформатированного представления прочитанных данных.
end( )
Функция end( ) перемещает указатель к позиции последнего элемента
массива. Синтаксис функции end( ):
end (array массив)
next( )
Функция next ( ) смещает указатель на одну позицию вперед, после чего
возвращает элемент, находящийся в новой позиции. Если в результате
смещения
указатель выйдет за пределы массива, next ( ) возвращает ложное
значение. Синтаксис функции next ( ):
mixed next (array массив)
Недостаток функции
next ( ) заключается в том, что ложное значение возвращается и для
существующих, но пустых элементов массива. Если вы хотите провести обычный
перебор, воспользуйтесь функцией each( ).
prev( )
Функция prev( ) аналогична next ( ) за одним исключением: указатель
смещается на одну позицию к началу массива, после чего возвращается
элемент, находящийся в новой позиции. Если в результате смещения указатель
окажется перед первым элементом массива, prev( ) вернет ложное значение.
Синтаксис функции prev( ):
mixed prev (array массив)
Недостаток функции prev( ) заключается в том, что ложное значение
возвращается и для существующих, но пустых элементов массива. Если вы
хотите провести обычный перебор, воспользуйтесь функцией each( ).
array_walk( )
Функция array_walk( ) позволяет применить функцию к нескольким (а
возможно, всем) элементам массива. Синтаксис функции array_walk( ):
int array_walk(array массив, string имя_функции [, mixed данные])
Функция, заданная параметром имя_функции, может использоваться для
различных целей — например, для поиска элементов с определенными
характеристиками или модификации содержимого массива. В ассоциативных
массивах функция имя_функции должна получать минимум два параметра —
элемент массива и ключ. Если указан необязательный третий параметр данные,
он становится третьим параметром. В следующем примере функция array_walk(
) используется для удаления дубликатов из массива:
function delete_dupes($element) {
static $last=""; if ($element == $last)
unset($element); else . ''
$last=$element:
}
$emails = array("blah@blah.com", "chef@wjgilmore.com",
"blah@blah.com");
sort($emails);
reset($emails);
array_walk($emails,"delete_dupes");
// $emails = array("chef@wjgilmore.com", "blah@blah.com");
array_reverse( )
Функция array_reverse( ) позволяет легко перейти к противоположному
порядку элементов, составляющих массив. Синтаксис функции array_reverse(
):
array array_reverse(array массив)
Рассмотрим пример использования функции array_reverse( ):
$us_wireproducers = array ("California", "Oregon", "New York".
"Washington");
$us_wine_producers - array_reverse (Sus_wine_producers);
// $us_wine_producers = array ("Washington". "New York", "Oregon".
"California");
При вызове array_reverse( ) для ассоциативного массива пары
«ключ/значение» сохраняются, изменяется только порядок элементов
массива.
array_flip( )
Функция array_flip( ) меняет местами ключи и значения элементов
массива. Синтаксис функции array_flip( ):
array array_flip(array массив)
В следующем примере функция array_flip( ) меняет местами все ключи и
значения элементов:
$languages = array("Spain" => "Spanish", "France" => "French",
"Italy" => "Italian");
$languages = array_flip($languages);
// $languages = array("Spanish" => "Spain", // "French" =>
"France", // "Italian" => "Italy");
Помните: функция array_flip( ) не изменяет порядок элементов массива.
Для этой цели используется функция array_reverse( ).
Наличие информации о текущем размере массива часто позволяет повысить
эффективность сценария. Вероятно, размер массива чаще всего используется
при циклическом переборе элементов:
$us_wine_producers = array ("Washington". "New York", "Oregon",
"California");
for (Si = 0; Si < sizeof ($us_wine_producers); $i++) :
print "$us_wine_producers[$i]";
endfor;
Поскольку массив $us_wine_producers индексируется целыми числами, мы
можем воспользоваться циклом for для циклического увеличения
переменной-счетчика ($i) и вывода каждого элемента в массиве.
sizeof( )
Функция sizeof ( ) возвращает количество элементов в массиве. Синтаксис
функции sizeof ( ):
int sizeof (array массив)
Вероятно, функция sizeof ( ) будет часто встречаться в ваших
web-приложениях. Ниже приведен краткий пример ее использования (кстати,
предыдущий пример тоже относится к числу стандартных применений sizeof (
)):
$pasta = array("bowties", "angelhair", "rigatoni");
$pasta_size = sizeof($pasta);
// $pasta_size = 3
У функции sizeof ( ) существует и другая, расширенная форма — count ( )
(см. ниже).
count( )
Функция count( ) выполняет ту же операцию, что и sizeof ( ), — она
возвращает количество значений, содержащихся в массиве. Синтаксис функции
count ( ):
int count (mixed переменная)
Единственное различие между sizeof ( ) и count( ) заключается в том,
что в некоторых ситуациях count ( ) возвращает дополнительную
информацию:
- если переменная существует и является массивом, count ( ) возвращает
количество элементов в массиве;
- если переменная существует, но не является массивом, функция
возвращает значение 1;
- если переменная не существует, возвращается значение 0.
array_count_values( )
Функция array_count_values( ) является разновидностью sizeof ( ) и
count ( ). Вместо общего количества элементов она подсчитывает количество
экземпляров каждого значения в массиве. Синтаксис функции
array_count_values( ):
array array_count_values(array массив):
В возвращаемом массиве ключами будут значения исходного массива, а
значениями — их частоты:
$states = аrrау("ОН", "ОК", "СА", "РА", "ОН", "ОН", "РА", "АК");
$state_freq = array_count_values($states);
Массив $state_freq заполняется следующими ассоциативными парами
«ключ/значение»:
$state_freq = аrrау("ОН" => 3, "ОК" => 1, "СА" => 1, "РА"
=> 2, "АК" => 1);
Сортировка массивов
Сортировка занимает важное место в программировании и часто встречается
на практике в таких Интернет-приложениях, как коммерческие сайты
(сортировка категорий товаров в алфавитном порядке, сортировка цен) или
поисковые системы (сортировка программ по количеству загрузок). В РНР
существует девять стандартных функций сортировки (табл. 5.1), причем
каждая функция сортирует массив особым образом.
Таблица 5.1. Функции сортировки
Функция |
Сортировка |
Обратный порядок |
Сохранение пар «ключ/значение» |
sort |
Значение |
Нет |
Нет |
rsort |
Значение |
Да |
Нет |
asort |
Значение |
Нет |
Да |
arsort |
Значение |
Да |
Да |
ksort |
Ключ |
Нет |
Да |
krsort |
Ключ |
Да |
Да |
usort |
Значение |
? |
Нет |
uasort |
Значение |
? |
Да |
uksort |
Ключ |
? |
Да |
? относится к применению пользовательских функций сортировки, когда
порядок сортировки массива зависит от результатов, возвращаемых
пользовательской функцией.
Сортировка элементов массива не ограничивается стандартными критериями,
поскольку три функции (usort(), uasort( ) и uksort( )) позволяют задать
пользовательский критерий и отсортировать информацию произвольным
образом.
sort( )
Простейшая функция sort( ) сортирует элементы массива по возрастанию
(от меньших к большим). Синтаксис функции sort ( ):
void sort (array массив)
Нечисловые элементы сортируются в алфавитном порядке в соответствии с
ASCII-кодами. Следующий пример демонстрирует применение функции sort( )
при сортировке:
// Создать массив городов.
$cities = array("Aprilia", "Nettuno", "Roma", "Venezia", "Anzio");
// Отсортировать города по возрастанию
sort($cities);
// Перебрать содержимое массива и вывести все пары "ключ/значение".
for (reset($cities); $key = key ($cities); next ($cities)):
print("cities[$key] = $cities[$key] <br>";
endfor;
Этот фрагмент выводит следующий результат:
cities[0] = Anzio
cities[1] = Aprilia
cities[2] = Nettuno
cities[3] = Roma
cities[4] = Venezia
Как видите, массив $cities сортируется в алфавитном порядке. Одна из
разновидностей этого способа сортировки реализована в функции asort( ),
описанной ниже.
rsort( )
Функция rsort ( ) работает точно так же, как функция sort ( ), за одним
исключением: элементы массива сортируются в обратном порядке. Синтаксис
функции rsort ( ):
void rsort (array массив)
Вернемся к массиву $cities из предыдущего примера:
$cities array("Aprilia", "Nettuno", "Roma", "Venezia", "Anzio");
rsort($cities);
В результате сортировки массива $cities функцией rsort( ) элементы
будут расположены в следующем порядке:
cities[0] = Venezia
cities[1] = Roma
cities[2] = Nettuno
cities[3] = Aprilia
cities[4] = Anzio
Массив $cities также сортируется, но на этот раз в порядке, обратном
алфавитному. Одна из разновидностей этого способа сортировки реализована в
функции arsort( ), описанной ниже.
asort( )
Функция asort( ) работает почти так же, как упоминавшаяся выше функция
sort( ), однако она сохраняет исходную ассоциацию индексов с элементами
независимо от нового порядка элементов. Синтаксис функции asort( ):
void asort(array массив)
Вернемся к массиву $cities:
$cities = array("Aprilia", "Nettuno", "Roma", "Venezia", "Anzio");
asort($cities):
В результате сортировки массива $cities функцией rsort() элементы будут
расположены в следующем порядке:
cities[4] = Anzio
cities[0] = Aprilia
cities[1] = Nettuno
cities[2] = Roma
cities[3] = Venezia
Обратите внимание на индексы и сравните их с приведенными в описании
функции sort ( ). Именно в этом и состоит различие между двумя
функциями.
arsort( )
Функция arsort ( ) представляет собой разновидность asort( ), которая
сохраняет исходную ассоциацию индексов, но сортирует элементы в обратном
порядке. Синтаксис функции arsort( ):
void arsort (array массив)
Воспользуемся функцией arsort( ) для сортировки массива $cities:
$cities = array("Aprilia", "Nettuno", "Roma", "Venezia", "Anzio");
arsort($cities);
В результате сортировки элементы будут расположены в следующем
порядке:
cities[3] = Venezia
cities[2] = Roma
cities[l] = Nettuno
cities[0] = Aprilia
cities[4] = Anzio
Обратите внимание на индексы и сравните их с приведенными в описании
функции rsort( ). Именно в этом и состоит различие между двумя
функциями.
ksort( )
Функция ksort( ) сортирует массив по ключам, сохраняя исходные
ассоциации ключей со значениями. Синтаксис функции ksort( ):
void ksort (array массив)
Для примера рассмотрим массив, слегка отличающийся от исходного
массива
$cities:
$wine_producers = array ("America" => "Napa Valley",
"Italy" => "Tuscany",
"Australia" => "Ruthgerlen",
"France" => "Loire",
"Chile" => "Rapel Valley");
В результате сортировки массива функцией ksort( ) элементы будут
расположены в следующем порядке:
"America" => "Napa Valley"
"Australia" => "Ruthgerlen"
"Chile" => "Rapel Valley"
"France" => "Loire"
"Italy" => "Tuscany"
Сравните с результатами сортировки $wine_producers функцией sort (
):
"America" => "Napa Valley"
"Australia" => "Tuscany"
"Chile" => "Ruthgerlen"
"France" => "Loire"
"Italy" => "Rapel Valley"
Более чем сомнительный результат!
krsort( )
Функция krsort( ) почти аналогична ksort( ), однако ключи сортируются в
обратном порядке. Синтаксис функции krsort( ):
void krsort (array $массив)
Рассмотрим сортировку массива $wi reproducers функцией krsort( ):
$wine_producers = array ("America" => "Napa Valley",
"Italy" => "Tuscany",
"Australia" => "Ruthgerlen",
"France" => "Loire".
"Chile" => "Rapel Valley");
krsort($wine_producers);
В результате сортировки элементы будут расположены в следующем
порядке:
"Italy" => "Tuscany"
"France" => "Loire"
"Chile" => "Rapel Valley"
"Australia" => "Ruthgerlen"
"America" => "Napa Valley"
Вероятно, описанных выше функций сортировки будет вполне достаточно для
большинства случаев. Тем не менее, в некоторых ситуациях может возникнуть
необходимость в определении собственных критериев сортировки. В РНР такая
возможность реализована в трех стандартных функциях: usort( ), uasort( ) и
uksort( ).
usort( )
Функция usort( ) дает возможность отсортировать массив на основании
критерия, определяемого программистом. Для этого usort( ) в качестве
параметра передается имя функции, определяющей порядок сортировки.
Синтаксис функции usort( ):
void usort (array массив, string имя_функции)
В параметре массив передается имя сортируемого массива, а в параметре
имя_функции — имя функции, на основании которой будет осуществляться
сортировка. Допустим, у вас имеется длинный список греческих имен, которые
необходимо выучить к предстоящему экзамену по истории. Вы хотите
отсортировать слова по длине, чтобы начать с самых длинных, а затем учить
короткие, когда вы уже устанете. Для сортировки массива по длине можно
воспользоваться функцией usort( ).
Листинг 5.2. Определение критерия сортировки для функции usort( )
$vocab = аrrау( "Socrates", "Aristophanes", "Plato", "Aeschylus",
"Thesmophoriazusae");
function compare_length($str1, $str2) {
// Получить длину двух следующих слов
$length1 = strlen($str1);
$length2 = strlen($str2);
// Определить, какая строка имеет меньшую длину
if ($length1 == $length2) :
return 0;
elseif ($length1 < $length2) :
return -1;
else :
return 1;
endif;
}
// Вызвать usort() с указанием функции compare_length()
// в качестве критерия сортировки
usort ($vocab, "compare_length") :
// Вывести отсортированный список
while (list ($key, $val) = each ($vocab)) {
echo "$val<br>";
}
В листинге 5.2 функция compare_length ( ) определяет критерий
сортировки массива. В данном случае это делается посредством сравнения
длины передаваемых элементов. Функция-критерий должна получать два
параметра, представляющих
сравниваемые элементы массива. Также обратите внимание на то, как эти
элементы неявно передаются функции-критерию при вызове usort( ), и на то,
что все элементы автоматически сравниваются этой функцией.
Функции uasort( ) и uksort( ) представляют собой разновидности usort( )
с тем же синтаксисом. Функция uasort() сортирует массив по
пользовательскому критерию с сохранением ассоциаций «ключ/значение».
Функция uksort( ) также сортирует массив по пользовательскому критерию,
однако сортируются не значения, а ключи.
Другие полезные функции
В этом разделе описаны некоторые функции, которые не принадлежат ни к
какому конкретному разделу, но приносят несомненную пользу.
array_merge( )
Функция arrayjnerge( ) сливает от 1 до N массивов, объединяя их в
соответствии с порядком перечисления в параметрах. Синтаксис функции
array_merge( ):
array array_merge(array массив1, array массив2, ..., array массивN]
Рассмотрим пример простого объединения массивов функцией arrayjnerge(
);
$arr_1 = array("strawberry", "grape", "lemon");
$arr_2 = array("banana", "cocoa", "lime");
$arr_3 = array("peach", "orange");
$arr_4 = array_merge ($arr2, $arr_1, $arr_3):
// $arr_4 = array("banana", "cocoa", "lime", "strawberry", "grape",
"lemon", "peach", "orange");
array_slice( )
Функция array_slice( ) возвращает часть массива, начальная и конечная
позиция которой определяется смещением от начала и необязательным
параметром длины. Синтаксис функции array_slice( ):
array array_slice(array массив, int смещение [, int длина])
Значения параметров задаются по определенным правилам:
- Если смещение положительно, начальная позиция возвращаемого
фрагмента отсчитывается от начала массива.
- Если смещение отрицательно, начальная позиция возвращаемого
фрагмента отсчитывается от конца массива.
- Если длина не указана, в возвращаемый массив включаются все элементы
от начальной позиции до конца массива.
- Если указана положительная длина, возвращаемый фрагмент состоит из
заданного количества элементов.
- Если указана отрицательная длина, возвращаемый фрагмент
заканчивается в заданном количестве элементов от конца массива.
array_splice( )
Функция array_spl ice( ) отдаленно напоминает array_slice( ) — она
заменяет часть массива, определяемую начальной позицией и необязательной
длиной, элементами необязательного параметра-массива. Синтаксис функции
array_splice( ):
array_splice(array входной_массив, int смещение, [int длина], [array
заменяющий_массив]);
Значения параметров задаются по определенным правилам:
- Если смещение положительно, начальная позиция первого удаляемого
элемента отсчитывается от начала массива.
- Если смещение отрицательно, начальная позиция первого удаляемого
элемента отсчитывается от конца массива.
- Если длина не указана, удаляются все элементы от начальной позиции
до конца массива.
- Если указана положительная длина, удаляемый фрагмент состоит из
заданного количества элементов.
- Если указана отрицательная длина, из массива удаляются элементы от
начальной позиции до позиции, находящейся на заданном расстоянии от
конца массива.
- Если заменяющий_массив не указан, то элементы, заданные смещением и
необязательной длиной, удаляются из массива.
- Если заменяющий_массив указан, он должен быть заключен в конструкцию
аггау() (если он содержит более одного элемента).
Рассмотрим несколько примеров, наглядно демонстрирующих возможности
этой функции. В этих примерах будет использоваться массив $pasta (см.
выше), с которым будут выполняться различные операции.
Удаление всех элементов с пятой позиции до конца массива:
$pasta = array_splice($pasta, 5);
Удаление пятого и шестого элементов:
$pasta = array_splice($pasta. 5, 2);
Замена пятого и шестого элементов новыми значениями:
$pasta = array_splice($pasta, 5, 2, array("element1", "element2"));
Удаление всех элементов, начиная с пятого, до третьего элемента с конца
массива:
$pasta = array_splice($pasta, 5, -3);
Как видно из приведенных примеров, функция array_splice( ) обеспечивает
гибкие возможности удаления элементов из массива при минимальном объеме
кода.
shuffle( )
Функция shuffle( ) сортирует элементы массива в случайном порядке.
Синтаксис функции shuffle( ):
void shuffle(array массив);
Итоги
В этой главе рассматривались массивы и стандартные функции РНР для
работы с массивами. В частности, рассматривались следующие темы:
- создание индексируемых и ассоциативных массивов;
- многомерные массивы;
- отображение содержимого многомерных массивов;
- поиск элементов;
- добавление и удаление элементов;
- размер массива;
- сортировка;
- другие полезные функции для работы с массивами.
Массивы являются очень удобными и универсальными средствами для работы
с данными в web-приложениях. В примерах дальнейших глав массивы будут
неоднократно использоваться для повышения эффективности и наглядности
кода.
В главе 6 мы продолжим знакомиться с базовыми средствами РНР. На этот
раз речь пойдет об объектно-ориентированных возможностях
языка.