- •Тема 1 Основы cgi-программирования
- •1.1 Методы передачи данных
- •1.2 Передача документа пользователю
- •1.3 Передача информации cgi-сценарию
- •Тема 2 Характеристика языка php
- •2.1 Принцип работы php
- •2.2 Переменные, константы, выражения
- •Тема 3 Работа с данными формы
- •3.1 Передача данных
- •3.2 Трансляция полей формы в переменные
- •Тема 4 Конструкции языка
- •4.1 Условные инструкции
- •4.2 Инструкции циклов
- •4.3 Инструкции включения
- •Тема 5 Ассоциативные массивы
- •5.1 Списки и ассоциативные массивы
- •5.2 Операции над массивами
- •5.3 Списки и строки
- •5.4 Сериализация
- •Тема 6 Работа с массивами
- •6.1 Сортировка массивов
- •6.2 Функции для работы с массивами
- •Тема 7 Функции и области видимости
- •7.1 Формат определения функции, передача параметров
- •7.2 Глобальные, локальные, статические переменные
- •7.3 Рекурсия, вложенные и условно-определяемые функции
- •7.4 Передача функций по ссылке и возврат функцией ссылки
- •Тема 8 Строковые функции
- •8.1 Функции работы со строками
- •8.2 Работа с блоками текста
- •Тема 9 Математические функции
- •9.1 Встроенные константы
- •9.2 Встроенные функции
- •Тема 10 Работа с файлами и каталогами,
- •10.1 Функции работы с файлами
- •10.2 Блокирование файла
- •10.3 Функции работы с каталогами
- •10.4 Запуск внешних программ
- •Тема 11 Работа с датами и временем,
- •11.1 Представление времени в формате timestamp
- •11.2 Работа с датами, григорианский календарь
- •11.3 Посылка писем через php
- •Тема 12 Работа с www
- •12.1 Установка заголовков ответа
- •12.2 Работа с Cookies
- •Тема 13 Управление интерпретатором
- •13.1 Управление интерпретатором
- •13.2 Управление сессиями
- •Тема 14 Работа с базой данных mysql
- •14.1 Соединение с базой данных
- •14.2 Выполнение запросов к базе данных
- •Тема 15 Загрузка файлов на сервер
- •15.1 Multipart-формы, тег выбора файла
- •15.2 Поддержка закачки в php
- •Учебное издание
- •Разработка программного обеспечения на платформе net: php.Net
- •246019 Г. Гомель, ул. Советская, 104
Тема 5 Ассоциативные массивы
5.1 Списки и ассоциативные массивы
5.2 Операции над массивами
5.3 Списки и строки
5.4 Сериализация
5.1 Списки и ассоциативные массивы
Особенности ассоциативных массивов:
1. Все массивы PHP являются ассоциативными (в частности, списки – тоже).
2. Ассоциативные массивы в РНР являются направленными, т.е. в них существует определенный (и предсказуемый) порядок элементов, не зависящий от реализации, а значит, есть первый и последний элементы, и для каждого элемента можно определить следующий за ним.
3. Операция [] всегда добавляет элемент в конец массива, присваивая ему при этом такой числовой индекс, который бы не конфликтовал с уже имеющимися массиве (выбирается номер, превосходящий все имеющиеся цифровые ключи в массиве).
4. Операция $Array[ключ]=значение добавляет элемент в конец массива, за исключением тех случаев, когда ключ уже присутствует в массиве.
5. Для изменения порядка следования элементов в ассоциативном массиве, не изменяя их ключей, можно воспользоваться функциями сортировки, или создать новый пустой массив и заполнить его в нужном порядке, пройдясь по элементам исходного массива.
5.2 Операции над массивами
Над массивами можно выполнять следующие операции:
Инициализация массива.
$NamesList[0]="Dmitry";
$NamesList[l]="Helen";
$NamesList [2]="Sergey";
Печать элементов массива. Количество элементов в массиве легко можно определить функцией count() или ее синонимом sizeof():
for($i=0; $i<count($NamesList); $i++)
echo $NamesList[$i]."<br>";
Добавление элементов в массив (создание массива «на лету»). Автомассивы. Для добавления элемента в конец массива можно не задавать номер элемента массива.
$NamesList[]="Dmitry";
$NamesList[]="Helen";
$NamesList[]="Sergey";
В этом случае РНР сам начнет (если переменная $NamesList не существует) нумерацию с нуля и каждый раз будет прибавлять к счетчику по единичке, создавая список.
Ассоциативный массив часто называется просто хэш.
Добавление элементов в ассоциативный массив осуществляется аналогично, только вместо цифровых ключей нужно указывать строковые. При этом следует помнить, что в строковых ключах буквы нижнего и верхнего регистров считаются различными. Ключом может быть абсолютно любая строка, содержащая пробелы, символы перевода строки, нулевые символы и т.д., т.е. никаких ограничений на ключи не накладывается.
Пример. Пусть необходимо написать сценарий, который работает, как записная книжка: по фамилии абонента выдает его имя. Можно организовать базу данных этой книжки в виде ассоциативного массива с ключами – фамилиями и соответствующими им значениями имен людей:
$Names["Koteroff"]="Dmitry";
$Names["Ivanov"]="Ivan";
$Names["Petrov"]="Peter";
Имя любого абонента можно распечатать командой:
echo $Names["Ivanov"] ;
$f="Koteroff";
echo $Names[$f];
Инструкция list(). Пусть есть некоторый массив-список $List с тремя элементами: имя человека, его фамилия и возраст. Нужно присвоить переменным $name, $surname и $age эти величины. Это можно сделать следующим образом:
$name=$List[0];
$surname=$List[1] ;
$age=$List[2];
Однако лучше воспользоваться инструкцией list():
list($name, $surname, $age)=$List;
Если в массиве не хватит элементов, чтобы их заполнить, им присвоятся неопределенные значения. Если нужны только второй и третий элемент массива $List, нужно пропустить первый параметр в инструкции list():
list(,$surname,$age)=$List;
Можно пропускать любое число элементов, как слева или справа, так и посередине списка. Главное – не забыть проставить нужное количество запятых.
Инструкция аrrау() и многомерные массивы. Пусть необходимо написать программу, которая по фамилии некоторого человека из группы будет выдавать его имя. Данные хранятся в ассоциативном массиве:
$Names["Ivanov"]="Dmitry";
$Names ["Petrova"]="Helen";
Теперь можно написать:
echo $Names["Petrova"]; // выведет Helen
echo $Names["Oshibkov"]; // ошибка: в массиве нет такого
// элемента!
То есть, таким образом нельзя создать пустой массив.
Второй способ создания массивов – это использование оператора array().
//создает пустой массив $Names
$Names=array();
//создает такой же массив, как в предыдущем примере с именами
$Names=array ("Ivanov"=>"Dmitry",
"Petrova"=>"Helen")
//создает список с именами (нумерация 0,1,2)
$NamesList=array("Dmitry","Helen","Sergey");
Создание двумерных массивов. Если кроме имени о человеке известен также его возраст, то можно инициализировать массив $Names следующим образом:
$Names["Ivanov"]=array("name"=>"Dmitry","age"=>25);
$Names["Petrova"]=array("name"=>"Helen","age"=>23);
или так:
$Names=аrraу(
"Ivanov"=>array("name"=>"Dmitry","age"=>25) ,
"Petrova"=>array("name"=>"Helen","age"=>23));
Получить нужный элемента массиве можно следующим образом:
echo $Names["Ivanov"]["age"]; // напечатает "25"
echo $Names["Petrova"]["bad"]; // ошибка: нет такого
// элемента "bad"
Ассоциативные массивы в РНР удобно использовать как некие структуры, хранящие данные. Это похоже на конструкцию struct в Си (или record в Паскале). Это единственный возможный способ организации структур, но он очень гибок.
Доступ по ключу.
//выводит элемент массива $Аrr с ключом anykey
echo $Arr ["anykey"];
//так используются двумерные массивы
echo $Arr ["first"]["second"];
echo $Arr[5];
Величина $Arr[ключ] является полноценным «левым значением», т. е. может стоять в левой части оператора присваивания, от нее можно брать ссылку с помощью оператора &, например:
//присваиваем элементу массива 100
$Arr["anykey"]=array(100,200);
//$ref – синоним элемента массива
$ref=&$Arr["first"]["second"];
$Arr[]="for add"; // добавляем новый элемент
Функция соunt() – определяет число элементов массива:
$num=count($Names); // $num – число элементов в массиве
Слияние массивов, т.е. создание массива, содержащего как элементы одного, так и другого массива. Реализуется при помощи оператора +. Например:
$а=аrrау("а"=>"аа", "b"=>"bb") ;
$b=array("c"=>"cc", "d"=>"dd");
$c=$a+$b;
В результате в $с окажется ассоциативный массив, содержащий все 4 элемента:
array("a"=>"aa","b"=>"bb","c"=>"cc","d"=>"dd"),
причем именно в указанном порядке.
Направленность массивов заставляет оператор + стать некоммутативным, т. е. $а+$b не равно $b+$а, если $а и $b массивы.
Так как списки являются тоже ассоциативными массивами, оператор + будет работать с ними неправильно! При слиянии списков:
$а=аrrау(10,20,30);
$b=array(100,200);
$c=$a+$b;
в $с будет array(10,20,30) !
Потому что при конкатенации массивов с одинаковыми элементами (то есть, элементами с одинаковыми ключами) в результирующем массиве останется только один элемент с таким же ключом – тот, который был в первом массиве, и на том же самом месте.
При слиянии ассоциативных массивов
$а=аrraу("а"=>10, "b"=>20);
$b=array("b"=>"new?");
$a+=$b;
оператор += не обновит элементы $а при помощи элементов $b. В результате этих операций значение $а не изменится.
Обновить элементы в массиве $а можно с помощью цикла:
foreach ($b as $k=>$v) $a[$k]=$v;
Цепочка
$z=$a+$b+$c+ ...
эквивалентна
$z=$a; $z+=$b; $z+=$c; ...и т. д.
Оператор += для массивов добавляет в свой левый операнд элементы, перечисленные в правом операнде-массиве, если они еще не содержатся в массиве слева.
В массиве не может быть двух элементов с одинаковыми ключами, потому что все операции, применимые к массивам, всегда контролируют, чтобы этого не произошло!
Косвенный перебор элементов массива. Используется для перебора всех элементов массива.
Если массив – список:
//Пусть $Namеs – список имен. Распечатаем их в столбик
for($i=0; $i<count ($Names); $i++)
echo $Names[$i]."\n";
Переменную можно помещать в строку:
for ($i=0; $i<count($Names); $i++)
echo "$Names[$i]\n";
Можно помещать массивы в строки, заключив их в фигурные скобки вместе с символом $:
$Names=array(array('name'=>'Вася','age'=>20),
array('name'=>'Билл','аgе'=>40));
for ($i=0; $i<count($Names); $i++)
echo "{$Names[$i]['age']}\n";
Пусть массив $Names – ассоциативный: его ключи – имена людей, а значения, сопоставленные ключам – возраст этих людей. Для перебора такого массива можно воспользоваться следующей конструкцией:
for(Reset($Names);($k=key($Names));Next($Names))
echo "Возраст $k – {$Names[$k]} лет\n";
Кроме того, что массивы являются направленными, в них есть еще и такое понятие, как текущий элемент. Функция Reset() устанавливает этот элемент на первую позицию в массиве. Функция key() возвращает ключ, который имеет текущий элемент (если он указывает на конец массива, возвращается пустая строка, что позволяет использовать вызов key() в контексте второго выражения for), а функция Next() перемещает текущий элемент на одну позицию вперед.
Функции Reset() и Next() возвращают следующие значения:
– функция Reset() возвращает значение первого элемента массива (или пустую строку, если массив пуст);
– функция Next() возвращает значение элемента, следующего за текущим (или пустую строку, если такого элемента нет).
Если необходим перебор элементов массива с конца, то можно воспользоваться следующей конструкцией:
for(End($Names);($k=key($Names));Prev($Names))
echo "Возраст $k – {$Names[$k]} лет\n";
Функция End() устанавливает позицию текущего элемента в конец массива, a Prev() передвигает ее на один элемент назад.
Функция current() возвращает не ключ, а величину текущего элемента (если он не указывает на конец массива).
Основное достоинство косвенного перебора – «читабельность» и ясность кода, а также то, что массив можно перебрать как в одну, так и в другую сторону.
Недостатки косвенного перебора:
1 Вложенные циклы. Нельзя одновременно перебирать массив в двух вложенных циклах или функциях. Так как второй вложенный for «испортит» положение текущего элемента у первого for'a.
2 Нулевой ключ. Если в массиве встретится ключ 0:
for(Reset($Names);($k=key($Names));Next($Names))
echo "Возраст $k – {$Names[$k]} лет\n";
то в этом случае выражение ($k=key ($Names)), будет равно нулю и цикл оборвется.
Прямой перебор массива. В косвенном переборе сначала вычисляется очередной ключ, а затем по нему косвенно находится значение элемента массива, при прямом переборе на каждом «витке» цикла одновременно получается и ключ, и значение текущего элемента.
Классический перебор. Пусть массив $Names хранит связь имен людей и их возрастов. Перебрать этот массив при помощи прямого перебора можно следующим образом:
for(Reset($Names);list($k,$v)=each($Names);
/*пусто*/)
echo "Возраст $k – $v\n";
В начале заголовка цикла используется функция Reset(). Дальше переменным $k и $v присваивается результат работы функции each(). Третье условие цикла просто отсутствует.
Функция each() во-первых, возвращает список, нулевой элемент которого хранит величину ключа текущего элемента массива $Names, а первый – значение текущего элемента. Во-вторых, она продвигает указатель текущего элемента к следующей позиции. Если следующего элемента в массиве нет, то функция возвращает не список, a false. Поэтому она и размещена в условии цикла for и не указан третий блок операторов в цикле for: он просто не нужен, ведь указатель на текущий элемент и так смещается функцией each ().
Перебор в стиле РНР. Прямой перебор массивов можно осуществить с помощью функции foreach:
foreach($Names as $k=>$v)
echo "Возраст $k – $v\n";
Этот способ перебора работает с максимально возможной скоростью – даже быстрее, чем перебор списка при помощи for и числового счетчика.
