Учебник РНР (перевод Alexandr Pyramidin) Размещено на PHPClub.Net
Назад Глава 6. Типы Вперёд

Массивы

Массив в PHP это упорядоченная карта. Карта/map это тип, который отображает значения в ключи. Этот тип оптимизируется разными способами, поэтому вы можете использовать его как реальный массив или как список (вектор), хэш-таблицу (которая является реализацией карты), словарь/dictionary, коллекцию/collection, стэк/stack, очередь/queue и, возможно, что-то ещё. Поскольку вы можете иметь другой PHP-массив в качестве значения, вы можете также довольно легко симулировать деревья/trees.

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

Синтаксис

Специфицирование с помощью array()

Массив может быть создан конструкцией языка array(). Она принимает определённое количество разделённых запятыми пар key => value (ключ-значение).

key это либо integer, либо string. Если ключ это стандартное представление integer, он будет интерпретироваться как таковой (т.е. "8" будет интерпретироваться как 8, а "08" будет интерпретироваться как "08").

Значение может быть любым.

Если вы опускаете ключ, берётся максимальный целочисленный индекс, а новый key будет равен этому максимуму + 1. Поскольку целые числа могут быть отрицательными, это верно также и в отношении отрицательных индексов. Если, например наивысший индекс -6, это даст в результате для нового ключа -5. Если ещё нет ни одного целочисленного индекса, key будет 0 (нуль). Если вы специфицируете ключ, который уже имеет присвоенное значение, это значение будет перезаписано.

Использование true в качестве ключа будет вычисляться в integer 1 в качестве ключа. Использование false в качестве ключа будет вычисляться в integer 0 в качестве ключа. Использование NULL в качестве ключа будет вычисляться в пустую строку. Использование пустой строки в качестве ключа создаст (или перезапишет) ключ пустой строкой в качестве значения, это не то же самое, что использование пустых угловых скобок.

Вы не можете использовать массивы объектов в качестве ключей. Если это сделать, появится предупреждение: Illegal offset type.

array( [key =>] value
     , ...
     )
// key это либо string, либо неотрицательное integer
// value\значение может быть любым

Создание/модифицирование с помощью синтаксиса квадратных (угловых) скобок

Вы также можете модифицировать существующий массив, явно установив значения.

Это делается путём присвоения значений массиву через специфицирование key в квадратных скобках. Вы можете также опустить key, добавив пустую пару угловых скобок ("[]") паре имя-значение в этом случае.
$arr[key] = value;
$arr[] = value;
// key это либо string, либо неотрицательное integer
// value может быть любым

Если массив $arr ещё не существует, он будет создан. Итак, это альтернативный способ специфицирования массива. Для изменения конкретного значения просто присвойте ему новое значение. Если вы хотите удалить пару key/value, вы должны её unset().

Используемые функции

Имеется достаточное количество функций для работы с массивами, см. раздел функции массивов.

Примечание: Функция unset() позволяет отменить установку ключа массива. Не забудьте, что при этом массив НЕ реиндексируется.
$a = array( 1 => 'one', 2 => 'two', 3 => 'three' );
unset( $a[2] );
/* даст массив, который определён как
   $a = array( 1=>'one', 3=>'three');
   а НЕ как
   $a = array( 1 => 'one', 2 => 'three');
*/

Структура управления foreach существует специально для массивов. Она даёт возможность без усилий просматривать массив.

Массив может и не может

Почему $foo[bar] неправильно?

Вы всегда должны использовать кавычки вокруг индекса ассоциативного массива. Например, пишите $foo['bar'], а не $foo[bar]. Но почему не верна запись $foo[bar]? Вы могли встретить в старых скриптах такой синтаксис:
$foo[bar] = 'enemy';
echo $foo[bar];
// etc

Это неправильно, но работает. Тогда почему неправильно? Суть в том, что этот код содержит неопределённую константу (bar), а не строку 'bar' (обратите внимание на кавычки), и PHP может в дальнейшем определить константу, которая, к несчастью для вашего кода, имеет то же самое имя. Это работает, поскольку неопределённая константа конвертируется в строку с тем же именем.

Как указано в разделе синтаксис, между квадратными скобками ('[' и ']') должно иметься выражение. Это означает, что вы можете записать:
echo $arr[ foo(true) ];

Это пример использования return-значения функции в качестве индекса массива. PHP знает также и о константах, и вы можете увидеть спереди E_*.

$error_descriptions[E_ERROR] = "A fatal error has occured";
$error_descriptions[E_WARNING] = "PHP issued a warning";
$error_descriptions[E_NOTICE] = "This is just an informal notice";

Обратите внимание, что E_ERROR это такой же идентификатор, как и bar в первом примере. Но последний пример равносилен записи:

$error_descriptions[1] = "A fatal error has occured";
$error_descriptions[2] = "PHP issued a warning";
$error_descriptions[8] = "This is just an informal notice";

поскольку E_ERROR равна 1, etc.

Тогда как может работать $foo[bar]? Это работает, поскольку bar, по причине своего синтаксиса, ожидается как константное выражение. Однако в этом случае константа с именем bar не существует. PHP теперь принимает, что вы обозначили bar литерально как строку "bar", но что вы забыли указать кавычки.

Так почему же это неправильно?

Когда-нибудь в будущем команда PHP может добавить другую константу или ключевое слово, и у вас появятся проблемы. Например, вы уже не можете использовать слова empty и default таким способом, поскольку они являются теперь зарезервированными ключевыми словами.

Примечание: Когда вы переключите error_reporting на E_ALL, вы увидите, что PHP генерирует уведомления, когда используется index, который не определён (поместите строку error_reporting(E_ALL); в ваш скрипт).

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

Примеры

Тип array в PHP является очень подвижным, поэтому мы даём здесь несколько примеров, демонстрирующих всю мощь массивов.

// это ...
$a = array( 'color' => 'red'
          , 'taste' => 'sweet'
          , 'shape' => 'round'
          , 'name'  => 'apple'
          ,            4        // key будет 0
          );

// ... абсолютно эквивалентно этому
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name'] = 'apple';
$a[]        = 4;        // key будет 0

$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// и даст в результате массив array( 0 => 'a' , 1 => 'b' , 2 => 'c' ),
// или просто array('a', 'b', 'c')

Пример 6-4. Использование array()

// Массив как карта (свойств)
$map = array( 'version'    => 4
            , 'OS'         => 'Linux'
            , 'lang'       => 'english'
            , 'short_tags' => true
            );

// строго цифровые ключи
$array = array( 7
              , 8
              , 0
              , 156
              , -10
              );
// это то же самое, что и array( 0 => 7, 1 => 8, ...)

$switching = array(         10 // key = 0
                  , 5    =>  6
                  , 3    =>  7 
                  , 'a'  =>  4
                  ,         11 // key = 6 (максимум целочисленного индекса был 5)
                  , '8'  =>  2 // key = 8 (целое число!)
                  , '02' => 77 // key = '02'
                  , 0    => 12 // значение 10 будет перезаписано на 12
                  );

// пустой массив
$empty = array();

Пример 6-5. Коллекция

$colors = array('red','blue','green','yellow');

foreach ( $colors as $color ) {
    echo "Do you like $color?\n";
}

/* на выходе:
Do you like red?
Do you like blue?
Do you like green?
Do you like yellow?
*/

Заметьте, что в настоящее время нельзя изменять значения массива в таких циклах напрямую.
Но можно сделать так:
Пример 6-6. Коллекция
foreach ($colors as $key => $color) {
    // не будет работать:
    //$color = strtoupper($color);

    //работает:
    $colors[$key] = strtoupper($color);
}
print_r($colors);

/* на выходе:
Array
(
    [0] => RED
    [1] => BLUE
    [2] => GREEN
    [3] => YELLOW
)
*/

Следующий пример создаёт одномерный массив.

Пример 6-7. Одномерный индекс

$firstquarter  = array(1 => 'January', 'February', 'March');
print_r($firstquarter);

/* на выходе:
Array 
(
    [1] => 'January'
    [2] => 'February'
    [3] => 'March'
)
*/

Пример 6-8. Заполнение реального массива

// заполним массив всеми элементами директории
$handle = opendir('.');
while ($file = readdir($handle)) 
{
    $files[] = $file;
}
closedir($handle);

Массивы упорядочены. Вы можете изменять порядок в массиве, используя различные функции сортировки. См. функции массивов.

Пример 6-9. Сортировка массива

sort($files);
print_r($files);

Поскольку значение массива может быть любым, это может быть также другой массив. Так вы можете создать рекурсивный и многомерный массивы.

Пример 6-10. Рекурсивный и многомерный массивы

$fruits = array ( "fruits"  => array ( "a" => "orange"
                                     , "b" => "banana"
                                     , "c" => "apple"
                                     )
                , "numbers" => array ( 1
                                     , 2
                                     , 3
                                     , 4
                                     , 5
                                     , 6
                                     )
                , "holes"   => array (      "first"
                                     , 5 => "second"
                                     ,      "third"
                                     )
                );

Назад Оглавление Вперёд
Строки Вверх Объекты