Массив в PHP на самом деле является упорядоченной картой. Карта — это тип, который связывает значения с ключами . Этот тип оптимизирован для нескольких различных применений; его можно рассматривать как массив, список (вектор), хеш-таблицу (реализация карты), словарь, коллекцию, стек, очередь и, возможно, многое другое. Поскольку значениями массива могут быть другие массивы , деревья и многомерные массивы также возможны.

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

Указание с помощью array()

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

массив(
     ключ   => значение ,
     ключ2 => значение2 ,
     ключ3 => значение3 ,
    ...
)

Запятая после последнего элемента массива необязательна и может быть опущена. Обычно это делается для однострочных массивов, т.е. array(1, 2)предпочтительнее, чем array(1, 2, ). С другой стороны, для многострочных массивов обычно используется замыкающая запятая, так как это упрощает добавление новых элементов в конце.

Примечание :

Существует короткий синтаксис массива, который заменяется array()на [].

Пример #1 Простой массив

 "bar",
    "bar" => "foo",
);

// Using the short array syntax
$array = [
    "foo" => "bar",
    "bar" => "foo",
];
?>

Ключ может быть либо int , либо строкой . Значение может быть любого типа.

Кроме того, будут происходить следующие приведения клавиш :

  • Строка s, содержащая допустимые десятичные целые s, если перед числом не стоит +знак, будет приведена к типу int . Например, ключ на "8"самом деле будет храниться в папке 8. С другой стороны "08", не будет приведено, так как это недопустимое десятичное целое число.
  • Float также приводится к int s, что означает, что дробная часть будет усечена. Например, ключ на 8.7самом деле будет храниться в папке 8.
  • Bool также приводится к типу int , т.е. ключ trueбудет фактически храниться в , 1 а ключ falseв 0.
  • Null будет преобразован в пустую строку, т.е. ключ nullфактически будет храниться в "".
  • Массивы и объекты не могут использоваться в качестве ключей. Это приведет к предупреждению: Illegal offset type.

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

Пример #2 Пример приведения типов и перезаписи

 "a",
    "1"  => "b",
    1.5  => "c",
    true => "d",
);
var_dump($array);
?>

Приведенный выше пример выведет:

массив (1) {
  [1]=>
  строка(1) "д"
}

Поскольку все ключи в приведенном выше примере приведены к 1, значение будет перезаписано для каждого нового элемента, и останется "d"только последнее назначенное значение.

Массивы PHP могут содержать ключи int и string одновременно, поскольку PHP не различает индексированные и ассоциативные массивы.

Пример #3 Смешанные целочисленные и строковые ключи

 "bar",
    "bar" => "foo",
    100   => -100,
    -100  => 100,
);
var_dump($array);
?>

Приведенный выше пример выведет:

массив (4) {
  ["фу"]=>
  строка(3) "бар"
  ["бар"]=>
  строка(3) "фу"
  [100]=>
  интервал (-100)
  [-100]=>
  интервал(100)
}

Ключ является необязательным . Если он не указан, PHP будет использовать приращение наибольшего ранее использовавшегося ключа int .

Пример #4 Индексированные массивы без ключа

 

Приведенный выше пример выведет:

массив (4) {  [0]=>  строка(3) "фу"  [1]=>  строка(3) "бар"  [2]=>  строка(5) "привет"  [3]=>  строка(5) "мир" }

Можно указать ключ только для одних элементов и не указывать его для других:

Пример #5 Ключи не на всех элементах

 "c",
         "d",
);
var_dump($array);
?>

Приведенный выше пример выведет:

массив (4) {
  [0]=>
  строка(1) "а"
  [1]=>
  строка(1) "б"
  [6]=>
  строка(1) "с"
  [7]=>
  строка(1) "д"
}

Как видите, последнее значение "d"было присвоено ключу 7. Это потому, что самый большой целочисленный ключ до этого был 6.

Пример #6 Пример сложного приведения типов и перезаписи

Этот пример включает в себя все варианты приведения типов ключей и перезаписывания элементов.

 'a',
    '1'  => 'b', // the value "a" will be overwritten by "b"
    1.5  => 'c', // the value "b" will be overwritten by "c"
    -1 => 'd',
    '01'  => 'e', // as this is not an integer string it will NOT override the key for 1
    '1.5' => 'f', // as this is not an integer string it will NOT override the key for 1
    true => 'g', // the value "c" will be overwritten by "g"
    false => 'h',
    '' => 'i',
    null => 'j', // the value "i" will be overwritten by "j"
    'k', // value "k" is assigned the key 2. This is because the largest integer key before that was 1
    2 => 'l', // the value "k" will be overwritten by "l"
);

var_dump($array);
?>

Приведенный выше пример выведет:

массив (7) {
  [1]=>
  строка(1) "г"
  [-1]=>
  строка(1) "д"
  ["01"]=>
  строка(1) "е"
  ["1,5"]=>
  строка (1) "f"
  [0]=>
  строка(1) "ч"
  [""]=>
  строка(1) "j"
  [2]=>
  строка(1) "л"
}

Доступ к элементам массива с помощью синтаксиса квадратных скобок

Доступ к элементам массива можно получить с помощью array[key]синтаксиса.

Пример #7 Доступ к элементам массива

 "bar",
    42    => 24,
    "multi" => array(
         "dimensional" => array(
             "array" => "foo"
         )
    )
);

var_dump($array["foo"]);
var_dump($array[42]);
var_dump($array["multi"]["dimensional"]["array"]);
?>

Приведенный выше пример выведет:

строка(3) "бар"
инт (24)
строка(3) "фу"

Примечание :

До PHP 8.0.0 квадратные скобки и фигурные скобки могли использоваться взаимозаменяемо для доступа к элементам массива (например $array[42], $array{42} в приведенном выше примере они оба делали одно и то же). Синтаксис фигурных скобок устарел в PHP 7.4.0 и больше не поддерживается в PHP 8.0.0.

Пример #8 Разыменование массива

 

Примечание :

Попытка получить доступ к ключу массива, который не был определен, аналогична доступу к любой другой неопределенной переменной: E_NOTICEбудет выдано сообщение об ошибке -level, и результатом будет null.

Примечание :

Массив, разыменовывающий скалярное значение, не являющееся строкой , дает null. До PHP 7.4.0 это не выдавало сообщения об ошибке. Начиная с PHP 7.4.0, это проблема E_NOTICE; начиная с PHP 8.0.0 это вызывает проблемы E_WARNING.

Создание/изменение синтаксиса с квадратными скобками

Существующий массив можно изменить, явно задав в нем значения.

Это делается путем присвоения значений массиву с указанием ключа в скобках. Ключ также может быть опущен, что приведет к пустой паре квадратных скобок ( []).

$arr[ ключ ] = значение ; $arr[] = значение ; // ключ может быть int или string // значение может быть любым значением любого типа

Если $arr еще не существует или имеет значение nullили false, он будет создан, так что это также альтернативный способ создания массива . Однако такая практика не рекомендуется, потому что если $arr уже содержит какое-то значение (например, строку из переменной запроса), то это значение останется на месте и []может фактически обозначать оператор доступа к строке . Всегда лучше инициализировать переменную прямым присвоением.

Примечание . Начиная с PHP 7.1.0, применение оператора пустого индекса к строке приводит к фатальной ошибке. Раньше строка автоматически преобразовывалась в массив.

Примечание . Начиная с PHP 8.1.0 создание нового массива из falseзначения устарело. Создание нового массива из nullнеопределенных значений по-прежнему разрешено.

Чтобы изменить определенное значение, присвойте новое значение этому элементу, используя его ключ. Чтобы удалить пару ключ/значение, вызовите для нее функцию unset() .

 1, 12 => 2);

$arr[] = 56;    // This is the same as $arr[13] = 56;
                // at this point of the script

$arr["x"] = 42; // This adds a new element to
                // the array with key "x"
                
unset($arr[5]); // This removes the element from the array

unset($arr);    // This deletes the whole array
?>

Примечание :

Как упоминалось выше, если ключ не указан, берется максимальное из существующих индексов int , а новым ключом будет это максимальное значение плюс 1 (но не менее 0). Если индексов int еще не существует, ключ будет 0(ноль).

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

 $value) {
    unset($array[$i]);
}
print_r($array);

// Append an item (note that the new key is 5, instead of 0).
$array[] = 6;
print_r($array);

// Re-index:
$array = array_values($array);
$array[] = 7;
print_r($array);
?>

Приведенный выше пример выведет:

Множество
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
)
Множество
(
)
Множество
(
    [5] => 6
)
Множество
(
    [0] => 6
    [1] => 7
)

Полезные функции

Есть довольно много полезных функций для работы с массивами.

Примечание :

Функция unset() позволяет удалять ключи из массива . Имейте в виду, что массив не будет переиндексирован. Если требуется истинное поведение «удалить и сдвинуть», массив можно переиндексировать с помощью функции array_values() .

 'one', 2 => 'two', 3 => 'three');
unset($a[2]);
/* will produce an array that would have been defined as
   $a = array(1 => 'one', 3 => 'three');
   and NOT
   $a = array(1 => 'one', 2 =>'three');
*/

$b = array_values($a);
// Now $b is array(0 => 'one', 1 =>'three')
?>

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

Что можно и чего нельзя делать с массивами

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

Всегда используйте кавычки вокруг индекса массива строковых литералов. Например, $foo['bar']верно, а $foo[bar]нет. Но почему? Такой синтаксис часто встречается в старых сценариях:

 

Это неправильно, но это работает. Причина в том, что этот код имеет неопределенную константу ( bar), а не строку ( 'bar'- обратите внимание на кавычки). Это работает, потому что PHP автоматически преобразует голую строку ( строку без кавычек , которая не соответствует ни одному известному символу) в строку , содержащую голую строку . Например, если нет определенной константы с именем bar, тогда PHP заменит строку 'bar' и будет использовать ее.

Предупреждение

Запасной вариант для обработки неопределенной константы как пустой строки выдает ошибку уровня E_NOTICE. Это устарело, начиная с PHP 7.2.0, и выдает ошибку уровня E_WARNING. Начиная с PHP 8.0.0, он был удален и вызывает исключение Error .

Примечание . Это не означает, что ключ нужно всегда указывать в кавычках. Не заключайте в кавычки ключи, которые являются константами или переменными , так как это помешает PHP их интерпретировать.

 

Приведенный выше пример выведет:

Проверка 0:
Примечание: Неопределенный индекс: $i в /path/to/script.html в строке 9
Плохой:
Хорошо: 1
Примечание. Неопределенный индекс: $i в /path/to/script.html в строке 11.
Плохой:
Хорошо: 1

Проверка 1:
Примечание: Неопределенный индекс: $i в /path/to/script.html в строке 9
Плохой:
Хорошо: 2
Примечание. Неопределенный индекс: $i в /path/to/script.html в строке 11.
Плохой:
Хорошо: 2

Дополнительные примеры, демонстрирующие такое поведение:

 'apple', 'veggie' => 'carrot');

// Correct
print $arr['fruit'];  // apple
print $arr['veggie']; // carrot

// Incorrect.  This works but also throws a PHP error of level E_NOTICE because
// of an undefined constant named fruit
// 
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit];    // apple

// This defines a constant to demonstrate what's going on.  The value 'veggie'
// is assigned to a constant named fruit.
define('fruit', 'veggie');

// Notice the difference now
print $arr['fruit'];  // apple
print $arr[fruit];    // carrot

// The following is okay, as it's inside a string. Constants are not looked for
// within strings, so no E_NOTICE occurs here
print "Hello $arr[fruit]";      // Hello apple

// With one exception: braces surrounding arrays within strings allows constants
// to be interpreted
print "Hello {$arr[fruit]}";    // Hello carrot
print "Hello {$arr['fruit']}";  // Hello apple

// This will not work, and will result in a parse error, such as:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// This of course applies to using superglobals in strings as well
print "Hello $arr['fruit']";
print "Hello $_GET['foo']";

// Concatenation is another option
print "Hello " . $arr['fruit']; // Hello apple
?>

Когда для error_reporting установлено отображение E_NOTICEошибок уровня (например, установив для него значение E_ALL), такое использование сразу станет видимым. По умолчанию error_reporting не показывает уведомления.

Как указано в разделе о синтаксисе , то, что находится внутри квадратных скобок (' [' и ' ]'), должно быть выражением. Это означает, что такой код работает:

 

Это пример использования возвращаемого функцией значения в качестве индекса массива. PHP также знает о константах:

 

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

 

потому что E_ERRORравно 1и т.д.

Так почему тогда плохо?

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

Примечание . Повторюсь: внутри строки в двойных кавычках допустимо не заключать индексы массива в кавычки, поэтому это действительно так. Подробности о причинах см. в приведенных выше примерах, а также в разделе, посвященном синтаксическому анализу переменных в строках . "$foo[bar]"

Преобразование в массив

Для любого из типов int , float , string , bool и resource преобразование значения в массив приводит к массиву с одним элементом с нулевым индексом и значением скаляра, который был преобразован. Другими словами, (array)$scalarValueточно так же, как array($scalarValue).

Если объект преобразуется в массив , результатом является массив , элементами которого являются свойства объекта . Ключи — это имена переменных-членов с несколькими заметными исключениями: целочисленные свойства недоступны; частные переменные имеют имя класса, предшествующее имени переменной; защищенные переменные имеют '*' перед именем переменной. Эти предваряемые значения имеют NULбайты с обеих сторон. Неинициализированные типизированные свойства молча отбрасываются.

{1} = null;
    }
}

var_export((array) new A());
?>

Приведенный выше пример выведет:

множество (
  '' . "\0" . «А». "\0" . 'В' => НУЛЬ,
  '' . "\0" . '*' . "\0" . 'С' => НУЛЬ,
  'Д' => НУЛЬ,
  1 => НОЛЬ,
)

Это NULможет привести к неожиданному поведению:

 

Приведенный выше пример выведет:

массив (3) {
  ["БА"]=>
  НУЛЕВОЙ
  ["АА"]=>
  НУЛЕВОЙ
  ["АА"]=>
  НУЛЕВОЙ
}

В приведенном выше примере будет два ключа с именами «AA», хотя один из них на самом деле называется «\ 0A \ 0A».

Преобразование nullв массив приводит к пустому массиву .

Сравнение

Массивы можно сравнивать с помощью функции array_diff() и с помощью операторов массивов .

Распаковка массива

Массив с префиксом ...будет расширен на месте во время определения массива. Только массивы и объекты, которые реализуют Traversable , могут быть расширены. Распаковка массива с помощью ...доступна, начиная с PHP 7.4.0.

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

Пример #9 Простая распаковка массива

 'd']; //['a', 'b', 'c' => 'd']
?>

Распаковка массива с помощью ...оператора следует семантике функции array_merge() . То есть более поздние строковые ключи перезаписывают более ранние, а целочисленные ключи перенумеровываются:

Пример #10 Распаковка массива с повторяющимся ключом

 1];
$arr2 = ["a" => 2];
$arr3 = ["a" => 0, ...$arr1, ...$arr2];
var_dump($arr3); // ["a" => 2]

// integer key
$arr4 = [1, 2, 3];
$arr5 = [4, 5, 6];
$arr6 = [...$arr4, ...$arr5];
var_dump($arr6); // [1, 2, 3, 4, 5, 6]
// Which is [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6]
// where the original integer keys have not been retained.
?>

Примечание :

Ключи, которые не являются ни целыми числами, ни строками, вызывают ошибку TypeError . Такие ключи могут быть сгенерированы только объектом Traversable .

Примечание :

До PHP 8.1 распаковка массива со строковым ключом не поддерживается:

 4];
$arr3 = [...$arr1, ...$arr2];
// Fatal error: Uncaught Error: Cannot unpack array with string keys in example.php:5

$arr4 = [1, 2, 3];
$arr5 = [4, 5];
$arr6 = [...$arr4, ...$arr5]; // works. [1, 2, 3, 4, 5]
?>

Примеры

Тип массива в PHP очень универсален. Вот некоторые примеры:

 'red',
            'taste' => 'sweet',
            'shape' => 'round',
            'name'  => 'apple',
            4        // key will be 0
          );

$b = array('a', 'b', 'c');

// . . .is completely equivalent with this:
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name']  = 'apple';
$a[]        = 4;        // key will be 0

$b = array();
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';

// After the above code is executed, $a will be the array
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round', 
// 'name' => 'apple', 0 => 4), and $b will be the array 
// array(0 => 'a', 1 => 'b', 2 => 'c'), or simply array('a', 'b', 'c').
?>

Пример #11 Использование массива()

 4,
              'OS'         => 'Linux',
              'lang'       => 'english',
              'short_tags' => true
            );
            
// strictly numerical keys
$array = array( 7,
                8,
                0,
                156,
                -10
              );
// this is the same as array(0 => 7, 1 => 8, ...)

$switching = array(         10, // key = 0
                    5    =>  6,
                    3    =>  7, 
                    'a'  =>  4,
                            11, // key = 6 (maximum of integer-indices was 5)
                    '8'  =>  2, // key = 8 (integer!)
                    '02' => 77, // key = '02'
                    0    => 12  // the value 10 will be overwritten by 12
                  );
                  
// empty array
$empty = array();         
?>

Пример #12 Коллекция

 

Приведенный выше пример выведет:

Вам нравится красный цвет?
Вам нравится синий?
Вам нравится зеленый?
Вам нравится желтый?

Изменение значений массива напрямую возможно путем передачи их по ссылке.

Пример #13 Изменение элемента в цикле

 

Приведенный выше пример выведет:

Множество
(
    [0] => КРАСНЫЙ
    [1] => СИНИЙ
    [2] => ЗЕЛЕНЫЙ
    [3] => ЖЕЛТЫЙ
)

В этом примере создается массив с отсчетом от единицы.

Пример #14 Индекс с одним основанием

 'January', 'February', 'March');
print_r($firstquarter);
?>

Приведенный выше пример выведет:

Множество
(
    [1] => 'Январь'
    [2] => 'Февраль'
    [3] => 'Март'
)

Пример #15 Заполнение массива

 

Массивы упорядочены. Порядок можно изменить с помощью различных функций сортировки. Функцию count() можно использовать для подсчета количества элементов в массиве .

Пример #16 Сортировка массива

 

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

Пример #17 Рекурсивные и многомерные массивы

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

// Some examples to address values in the array above 
echo $fruits["holes"][5];    // prints "second"
echo $fruits["fruits"]["a"]; // prints "orange"
unset($fruits["holes"][0]);  // remove "first"

// Create a new multi-dimensional array
$juices["apple"]["green"] = "good"; 
?>

Назначение массива всегда включает копирование значения. Используйте оператор ссылки для копирования массива по ссылке.