Учебник РНР
Назад Глава 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"
                                     )
                );

Назад Оглавление Вперёд
Строки Вверх Объекты
Используются технологии uCoz