Массивы

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

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

Синтаксис

Определение при помощи array()

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

    array(
    key  => value,
    key2 => value2,
    key3 => value3,
    ...
    )

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

Замечание:

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

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

<?php
$array 
= array(
    
"foo" => "bar",
    
"bar" => "foo",
);

// Использование синтаксиса короткого массива
$array = [
    
"foo" => "bar",
    
"bar" => "foo",
];
?>

key может быть либо типа int, либо типа string. value может быть любого типа.

Дополнительно с ключом key будут сделаны следующие преобразования:

  • Строки (string), содержащие целое число (int) (исключая случаи, когда число предваряется знаком +) будут преобразованы к типу int. Например, ключ со значением "8" будет в действительности сохранён со значением 8. С другой стороны, значение "08" не будет преобразовано, так как оно не является корректным десятичным целым.
  • Числа с плавающей точкой (float) также будут преобразованы к типу int, то есть дробная часть будет отброшена. Например, ключ со значением 8.7 будет в действительности сохранён со значением 8.
  • Тип bool также преобразовываются к типу int. Например, ключ со значением true будет сохранён со значением 1 и ключ со значением false будет сохранён со значением 0.
  • Тип null будет преобразован к пустой строке. Например, ключ со значением null будет в действительности сохранён со значением "".
  • Массивы (array) и объекты (object) не могут использоваться в качестве ключей. При подобном использовании будет генерироваться предупреждение: Недопустимый тип смещения (Illegal offset type).

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

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

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

Результат выполнения данного примера:

array(1) {
  [1]=>
  string(1) "d"
}

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

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

Пример #3 Смешанные ключи типов int и string

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

Результат выполнения данного примера:

array(4) {
  ["foo"]=>
  string(3) "bar"
  ["bar"]=>
  string(3) "foo"
  [100]=>
  int(-100)
  [-100]=>
  int(100)
}

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

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

<?php
$array 
= array("foo""bar""hallo""world");
var_dump($array);
?>

Результат выполнения данного примера:

array(4) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
  [2]=>
  string(5) "hallo"
  [3]=>
  string(5) "world"
}

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

Пример #5 Ключи для некоторых элементов

<?php
$array 
= array(
         
"a",
         
"b",
    
=> "c",
         
"d",
);
var_dump($array);
?>

Результат выполнения данного примера:

array(4) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [6]=>
  string(1) "c"
  [7]=>
  string(1) "d"
}

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

Пример #6 Расширенный пример преобразования типов и перезаписи элементов

<?php
$array 
= array(
    
1    => 'a',
    
'1'  => 'b'// значение "b" перезапишет значение "a"
    
1.5  => 'c'// значение "b" перезапишет значение "c"
    
-=> 'd',
    
'01'  => 'e'// поскольку это не целочисленная строка, она НЕ перезапишет ключ для 1
    
'1.5' => 'f'// поскольку это не целочисленная строка, она НЕ перезапишет ключ для 1
    
true => 'g'// значение "c" перезапишет значение "g"
    
false => 'h',
    
'' => 'i',
    
null => 'j'// значение "i" перезапишет значение "j"
    
'k'// значение "k" присваивается ключу 2. Потому что самый большой целочисленный ключ до этого был 1
    
=> 'l'// значение "k" перезапишет значение "1"
);

var_dump($array);
?>

Результат выполнения данного примера:

array(7) {
  [1]=>
  string(1) "g"
  [-1]=>
  string(1) "d"
  ["01"]=>
  string(1) "e"
  ["1.5"]=>
  string(1) "f"
  [0]=>
  string(1) "h"
  [""]=>
  string(1) "j"
  [2]=>
  string(1) "l"
}

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

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

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

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

<?php
$array 
= array(
    
"foo" => "bar",
    
42    => 24,
    
"multi" => array(
         
"dimensional" => array(
             
"array" => "foo"
         
)
    )
);

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

Результат выполнения данного примера:

string(3) "bar"
int(24)
string(3) "foo"

Замечание:

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

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

<?php
function getArray() {
    return array(
123);
}

$secondElement getArray()[1];

// или так
list(, $secondElement) = getArray();
?>

Замечание:

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

Замечание:

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

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

Существующий массив может быть изменён путём явной установкой значений в нем.

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

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

Если массив $arr ещё не существует, он будет создан. Таким образом, это ещё один способ определить массив array. Однако такой способ применять не рекомендуется, так как если переменная $arr уже содержит некоторое значение (например, значение типа string из переменной запроса), то это значение останется на месте и [] может на самом деле означать доступ к символу в строке. Лучше инициализировать переменную путём явного присваивания значения.

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

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

<?php
$arr 
= array(=> 112 => 2);

$arr[] = 56;    // В этом месте скрипта это
                // то же самое, что и $arr[13] = 56;

$arr["x"] = 42// Это добавляет к массиву новый
                // элемент с ключом "x"

unset($arr[5]); // Это удаляет элемент из массива

unset($arr);    // Это удаляет массив полностью
?>

Замечание:

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

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

<?php
// Создаём простой массив.
$array = array(12345);
print_r($array);

// Теперь удаляем каждый элемент, но сам массив оставляем нетронутым:
foreach ($array as $i => $value) {
    unset(
$array[$i]);
}
print_r($array);

// Добавляем элемент (обратите внимание, что новым ключом будет 5, вместо 0).
$array[] = 6;
print_r($array);

// Переиндексация:
$array array_values($array);
$array[] = 7;
print_r($array);
?>

Результат выполнения данного примера:

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
)
Array
(
)
Array
(
    [5] => 6
)
Array
(
    [0] => 6
    [1] => 7
)

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

Для работы с массивами существует достаточное количество полезных функций. Смотрите раздел функции для работы с массивами.

Замечание:

Функция unset() позволяет удалять ключи массива. Обратите внимание, что массив НЕ будет переиндексирован. Если вы действительно хотите поведения в стиле "удалить и сдвинуть", можно переиндексировать массив используя array_values().

<?php
$a 
= array(=> 'один'=> 'два'=> 'три');
unset(
$a[2]);
/* даст массив, представленный так:
   $a = array(1 => 'один', 3 => 'три');
   а НЕ так:
   $a = array(1 => 'один', 2 => 'три');
*/

$b array_values($a);
// Теперь $b это array(0 => 'один', 1 => 'три')
?>

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

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

Почему $foo[bar] неверно?

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

<?php
$foo
[bar] = 'враг';
echo 
$foo[bar];
// и т.д.
?>

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

Внимание

Этот резервный вариант для обработки неопределённой константы в качестве пустой строки объявлен устаревшим с PHP 7.2.0 и генерирует ошибку уровня E_WARNING. Ранее выдавалась ошибка уровня E_NOTICE.

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

<?php
error_reporting
(E_ALL);
ini_set('display_errors'true);
ini_set('html_errors'false);
// Простой массив:
$array = array(12);
$count count($array);
for (
$i 0$i $count$i++) {
    echo 
"\nПроверяем $i: \n";
    echo 
"Плохо: " $array['$i'] . "\n";
    echo 
"Хорошо: " $array[$i] . "\n";
    echo 
"Плохо: {$array['$i']}\n";
    echo 
"Хорошо: {$array[$i]}\n";
}
?>

Результат выполнения данного примера:

Проверяем 0:
Notice: Undefined index:  $i in /path/to/script.html on line 9
Плохо:
Хорошо: 1
Notice: Undefined index:  $i in /path/to/script.html on line 11
Плохо:
Хорошо: 1

Проверяем 1:
Notice: Undefined index:  $i in /path/to/script.html on line 9
Плохо:
Хорошо: 2
Notice: Undefined index:  $i in /path/to/script.html on line 11
Плохо:
Хорошо: 2

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

<?php
// Показываем все ошибки
error_reporting(E_ALL);

$arr = array('fruit' => 'apple''veggie' => 'carrot');

// Верно
print $arr['fruit'];  // apple
print $arr['veggie']; // carrot

// Неверно. Это работает, но из-за неопределённой константы с
// именем fruit также вызывает ошибку PHP уровня E_NOTICE
//
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit];    // apple

// Давайте определим константу, чтобы продемонстрировать, что
// происходит. Мы присвоим константе с именем fruit значение 'veggie'.
define('fruit''veggie');

// Теперь обратите внимание на разницу
print $arr['fruit'];  // apple
print $arr[fruit];    // carrot

// Внутри строки это нормально. Внутри строк константы не
// рассматриваются, так что ошибки E_NOTICE здесь не произойдёт
print "Hello $arr[fruit]";      // Hello apple

// С одним исключением: фигурные скобки вокруг массивов внутри
// строк позволяют константам там находиться
print "Hello {$arr[fruit]}";    // Hello carrot
print "Hello {$arr['fruit']}";  // Hello apple

// Это не будет работать и вызовет ошибку обработки, такую как:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// Это, конечно, также действует и с суперглобальными переменными в строках
print "Hello $arr['fruit']";
print 
"Hello $_GET['foo']";

// Ещё одна возможность - конкатенация
print "Hello " $arr['fruit']; // Hello apple
?>

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

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

<?php
echo $arr[somefunc($bar)];
?>

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

<?php
$error_descriptions
[E_ERROR]   = "Произошла фатальная ошибка";
$error_descriptions[E_WARNING] = "PHP сообщает о предупреждении";
$error_descriptions[E_NOTICE]  = "Это лишь неофициальное замечание";
?>

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

<?php
$error_descriptions
[1] = "Произошла фатальная ошибка";
$error_descriptions[2] = "PHP сообщает о предупреждении";
$error_descriptions[8] = "Это лишь неофициальное замечание";
?>

поскольку E_ERROR соответствует 1 и т.д.

Так что же в этом плохого?

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

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

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

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

Если вы преобразуете в массив объект (object), вы получите в качестве элементов массива свойства (переменные-члены) этого объекта. Ключами будут имена переменных-членов, с некоторыми примечательными исключениями: целочисленные свойства станут недоступны; к закрытым полям класса (private) спереди будет дописано имя класса; к защищённым полям класса (protected) спереди будет добавлен символ '*'. Эти добавленные значения с обоих сторон также имеют нулевые байты.

<?php
class {
    private 
$B;
    protected 
$C;
    public 
$D;
    function 
__construct()
    {
        
$this->{1} = null;
    }
}
var_export((array) new A());
?>

Результат выполнения данного примера:

array (
  '' . "\0" . 'A' . "\0" . 'B' => NULL,
  '' . "\0" . '*' . "\0" . 'C' => NULL,
  'D' => NULL,
  1 => NULL,
)

Это может вызвать несколько неожиданное поведение:

<?php
class {
    private 
$A// Это станет '\0A\0A'
}
class 
extends {
    private 
$A// Это станет '\0B\0A'
    
public $AA// Это станет 'AA'
}
var_dump((array) new B());
?>

Результат выполнения данного примера:

array(3) {
  ["BA"]=>
  NULL
  ["AA"]=>
  NULL
  ["AA"]=>
  NULL
}

Вышеприведённый код покажет 2 ключа с именем 'AA', хотя один из них на самом деле имеет имя '\0A\0A'.

Если вы преобразуете в массив значение null, вы получите пустой массив.

Сравнение

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

Примеры

Тип массив в PHP является очень гибким, вот несколько примеров:

<?php
// это
$a = array( 'color' => 'red',
            
'taste' => 'sweet',
            
'shape' => 'round',
            
'name'  => 'apple',
            
4        // ключом будет 0
          
);

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

// . . .полностью соответствует
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name']  = 'apple';
$a[]        = 4;        // ключом будет 0

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

// после выполнения этого кода, $a будет массивом
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
// 'name' => 'apple', 0 => 4), а $b будет
// array(0 => 'a', 1 => 'b', 2 => 'c'), или просто array('a', 'b', 'c').
?>

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

<?php
// Массив как карта (свойств)
$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// ключ = 0
                    
5    =>  6,
                    
3    =>  7,
                    
'a'  =>  4,
                            
11// ключ = 6 (максимальным числовым индексом было 5)
                    
'8'  =>  2// ключ = 8 (число!)
                    
'02' => 77// ключ = '02'
                    
0    => 12  // значение 10 будет перезаписано на 12
                  
);

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

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

<?php
$colors 
= array('red''blue''green''yellow');

foreach (
$colors as $color) {
    echo 
"Вам нравится $color?\n";
}

?>

Результат выполнения данного примера:

Вам нравится red?
Вам нравится blue?
Вам нравится green?
Вам нравится yellow?

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

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

<?php
foreach ($colors as &$color) {
    
$color strtoupper($color);
}
unset(
$color); /* это нужно для того, чтобы последующие записи в
$color не меняли последний элемент массива */

print_r($colors);
?>

Результат выполнения данного примера:

Array
(
    [0] => RED
    [1] => BLUE
    [2] => GREEN
    [3] => YELLOW
)

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

Пример #12 Индекс, начинающийся с единицы

<?php
$firstquarter  
= array(=> 'Январь''Февраль''Март');
print_r($firstquarter);
?>

Результат выполнения данного примера:

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

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

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

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

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

<?php
sort
($files);
print_r($files);
?>

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

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

<?php
$fruits 
= array ( "fruits"  => array ( "a" => "апельсин",
                                       
"b" => "банан",
                                       
"c" => "яблоко"
                                     
),
                  
"numbers"   => array ( 1,
                                       
2,
                                       
3,
                                       
4,
                                       
5,
                                       
6
                                     
),
                  
"holes"   => array (      "первая",
                                       
=> "вторая",
                                            
"третья"
                                     
)
                );

// Несколько примеров доступа к значениям предыдущего массива
echo $fruits["holes"][5];    // напечатает "вторая"
echo $fruits["fruits"]["a"]; // напечатает "апельсин"
unset($fruits["holes"][0]);  // удалит "первая"

// Создаст новый многомерный массив
$juices["apple"]["green"] = "good";
?>

Обратите внимание, что при присваивании массива всегда происходит копирование значения. Чтобы скопировать массив по ссылке, вам нужно использовать оператор ссылки.

<?php
$arr1 
= array(23);
$arr2 $arr1;
$arr2[] = 4// $arr2 изменился,
             // $arr1 всё ещё array(2, 3)

$arr3 = &$arr1;
$arr3[] = 4// теперь $arr1 и $arr3 одинаковы
?>
add a note add a note

User Contributed Notes 20 notes

up
123
mlvljr
12 years ago
please note that when arrays are copied, the "reference status" of their members is preserved (http://www.php.net/manual/en/language.references.whatdo.php).
up
54
thomas tulinsky
8 years ago
I think your first, main example is needlessly confusing, very confusing to newbies:

$array = array(
    "foo" => "bar",
    "bar" => "foo",
);

It should be removed.

For newbies:
An array index can be any string value, even a value that is also a value in the array.
The value of array["foo"] is "bar".
The value of array["bar"] is "foo"

The following expressions are both true:
$array["foo"] == "bar"
$array["bar"] == "foo"
up
34
liberchen at gmail dot com
6 years ago
Since PHP 7.1, the string will not be converted to array automatically.

Below codes will fail:

$a=array();
$a['a']='';
$a['a']['b']=''; 
//Warning: Illegal string offset 'b'
//Warning: Cannot assign an empty string to a string offset

You have to change to as below:

$a=array();

$a['a']=array(); // Declare it is an array first
$a['a']['b']='';
up
29
Yesterday php&#39;er
7 years ago
--- quote ---
Note:
Both square brackets and curly braces can be used interchangeably for accessing array elements
--- quote end ---

At least for php 5.4 and 5.6; if function returns an array, the curly brackets does not work directly accessing function result, eg. WillReturnArray(){1} . This will give "syntax error, unexpected '{' in...".
Personally I use only square brackets, expect for accessing single char in string. Old habits...
up
59
jeff splat codedread splot com
19 years ago
Beware that if you're using strings as indices in the $_POST array, that periods are transformed into underscores:

<html>
<body>
<?php
    printf
("POST: "); print_r($_POST); printf("<br/>");
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    <input type="hidden" name="Windows3.1" value="Sux">
    <input type="submit" value="Click" />
</form>
</body>
</html>

Once you click on the button, the page displays the following:

POST: Array ( [Windows3_1] => Sux )
up
56
ken underscore yap atsign email dot com
16 years ago
"If you convert a NULL value to an array, you get an empty array."

This turns out to be a useful property. Say you have a search function that returns an array of values on success or NULL if nothing found.

<?php $values = search(...); ?>

Now you want to merge the array with another array. What do we do if $values is NULL? No problem:

<?php $combined = array_merge((array)$values, $other); ?>

Voila.
up
45
chris at ocportal dot com
10 years ago
Note that array value buckets are reference-safe, even through serialization.

<?php
$x
='initial';
$test=array('A'=>&$x,'B'=>&$x);
$test=unserialize(serialize($test));
$test['A']='changed';
echo
$test['B']; // Outputs "changed"
?>

This can be useful in some cases, for example saving RAM within complex structures.
up
42
ia [AT] zoznam [DOT] sk
18 years ago
Regarding the previous comment, beware of the fact that reference to the last value of the array remains stored in $value after the foreach:

<?php
foreach ( $arr as $key => &$value )
{
   
$value = 1;
}

// without next line you can get bad results...
//unset( $value );

$value = 159;
?>

Now the last element of $arr has the value of '159'. If we remove the comment in the unset() line, everything works as expected ($arr has all values of '1').

Bad results can also appear in nested foreach loops (the same reason as above).

So either unset $value after each foreach or better use the longer form:

<?php
foreach ( $arr as $key => $value )
{
   
$arr[ $key ] = 1;
}
?>
up
11
anisgazig at gmail dot com
5 years ago
//array keys are always integer and string data type and array values are all data type
//type casting and overwriting(data type of array key)
//----------------------------------------------------
$arr = array(
1=>"a",//int(1)
"3"=>"b",//int(3)
"08"=>"c",//string(2)"08"
"80"=>"d",//int(80)
"0"=>"e",//int(0)
"Hellow"=>"f",//string(6)"Hellow"
"10Hellow"=>"h",//string(8)"10Hellow"
1.5=>"j",//int(1.5)
"1.5"=>"k",//string(3)"1.5"
0.0=>"l",//int(0)
false=>"m",//int(false)
true=>"n",//int(true)
"true"=>"o",//string(4)"true"
"false"=>"p",//string(5)"false"
null=>"q",//string(0)""
NULL=>"r",//string(0)"" note null and NULL are same
"NULL"=>"s",//string(4)"NULL" ,,,In last element of multiline array,comma is better to used.
);
//check the data type name of key
foreach ($arr as $key => $value) {
var_dump($key);
echo "<br>";
}

//NOte :array and object data type in keys are Illegal ofset.......
up
2
ivail89 at mail dot ru
3 years ago
Function unset can delete array's element by reference only when you specify source array. See example:
<?php
$array
= [1, 2, 3, 4, 5];
foreach (
$array as $k => &$v){
    if (
$k >= 3){
        unset(
$v);
    }
}
echo
count($array); // 5
?>
In this case unset delete only reference, however original array didn't change.

Or different example:
<?php
$arr
= [1, 2];
$a = &$arr[0];
unset(
$a);
count($arr); // 2
?>

So for deleting element from first example need use key and array.
<?php
// ...
 
unset($array[$k]);
// ...
?>
up
31
lars-phpcomments at ukmix dot net
19 years ago
Used to creating arrays like this in Perl?

@array = ("All", "A".."Z");

Looks like we need the range() function in PHP:

<?php
$array
= array_merge(array('All'), range('A', 'Z'));
?>

You don't need to array_merge if it's just one range:

<?php
$array
= range('A', 'Z');
?>
up
3
dylanfj700 at gmail dot com
4 years ago
// Before php 5.4
$array = array(1,2,3);

// since php 5.4 , short syntax
$array = [1,2,3];

// I recommend using the short syntax if you have php version >= 5.4
up
7
tissus
6 years ago
In array(key=>value) construct key is also an expression.
This works fine:
  $a = array(
    1     =>0,
    1+1   =>1,
    $k    =>2,
    $x.'4'=>3
  );
up
22
caifara aaaat im dooaat be
18 years ago
[Editor's note: You can achieve what you're looking for by referencing $single, rather than copying it by value in your foreach statement. See http://php.net/foreach for more details.]

Don't know if this is known or not, but it did eat some of my time and maybe it won't eat your time now...

I tried to add something to a multidimensional array, but that didn't work at first, look at the code below to see what I mean:

<?php

$a1
= array( "a" => 0, "b" => 1 );
$a2 = array( "aa" => 00, "bb" => 11 );

$together = array( $a1, $a2 );

foreach(
$together as $single ) {
   
$single[ "c" ] = 3 ;
}

print_r( $together );
/* nothing changed result is:
Array
(
    [0] => Array
        (
            [a] => 0
            [b] => 1
        )
    [1] => Array
        (
            [aa] => 0
            [bb] => 11
        )
) */

foreach( $together as $key => $value ) {
   
$together[$key]["c"] = 3 ;
}

print_r( $together );

/* now it works, this prints
Array
(
    [0] => Array
        (
            [a] => 0
            [b] => 1
            [c] => 3
        )
    [1] => Array
        (
            [aa] => 0
            [bb] => 11
            [c] => 3
        )
)
*/

?>
up
7
note dot php dot lorriman at spamgourmet dot org
10 years ago
There is another kind of array (php>=  5.3.0) produced by

$array = new SplFixedArray(5);

Standard arrays, as documented here, are marvellously flexible and, due to the underlying hashtable, extremely fast for certain kinds of lookup operation.

Supposing a large string-keyed array

$arr=['string1'=>$data1, 'string2'=>$data2 etc....]

when getting the keyed data with

$data=$arr['string1'];

php does *not* have to search through the array comparing each key string to the given key ('string1') one by one, which could take a long time with a large array. Instead the hashtable means that php takes the given key string and computes from it the memory location of the keyed data, and then instantly retrieves the data. Marvellous! And so quick. And no need to know anything about hashtables as it's all hidden away.

However, there is a lot of overhead in that. It uses lots of memory, as hashtables tend to (also nearly doubling on a 64bit server), and should be significantly slower for integer keyed arrays than old-fashioned (non-hashtable) integer-keyed arrays. For that see more on SplFixedArray :

http://uk3.php.net/SplFixedArray

Unlike a standard php (hashtabled) array, if you lookup by integer then the integer itself denotes the memory location of the data, no hashtable computation on the integer key needed. This is much quicker. It's also quicker to build the array compared to the complex operations needed for hashtables. And it uses a lot less memory as there is no hashtable data structure. This is really an optimisation decision, but in some cases of large integer keyed arrays it may significantly reduce server memory and increase performance (including the avoiding of expensive memory deallocation of hashtable arrays at the exiting of the script).
up
-2
Denise Ignatova
6 years ago
When creating arrays , if we have an element with the same value as another element from the same array, we would expect PHP instead of creating new zval container to increase the refcount and point the duplicate symbol to the same zval. This is true except for value type integer.
Example:

$arr = ['bebe' => 'Bob', 'age' => 23, 'too' => 23 ];
xdebug_debug_zval( 'arr' );

Output:
arr:

(refcount=2, is_ref=0)
array (size=3)
  'bebe' => (refcount=1, is_ref=0)string 'Bob' (length=3)
  'age' => (refcount=0, is_ref=0)int 23
  'too' => (refcount=0, is_ref=0)int 23

but :
$arr = ['bebe' => 'Bob', 'age' => 23, 'too' => '23' ];
xdebug_debug_zval( 'arr' );

will produce:
arr:

(refcount=2, is_ref=0)
array (size=3)
  'bebe' => (refcount=1, is_ref=0)string 'Bob' (length=3)
  'age' => (refcount=0, is_ref=0)int 23
  'too' => (refcount=1, is_ref=0)string '23' (length=2)
or :

$arr = ['bebe' => 'Bob', 'age' => [1,2], 'too' => [1,2] ];
xdebug_debug_zval( 'arr' );

Output:
arr:

(refcount=2, is_ref=0)
array (size=3)
  'bebe' => (refcount=1, is_ref=0)string 'Bob' (length=3)
  'age' => (refcount=2, is_ref=0)
    array (size=2)
      0 => (refcount=0, is_ref=0)int 1
      1 => (refcount=0, is_ref=0)int 2
  'too' => (refcount=2, is_ref=0)
    array (size=2)
      0 => (refcount=0, is_ref=0)int 1
      1 => (refcount=0, is_ref=0)int 2
up
-2
Anonymous
4 years ago
Wrappers for (array), returns array with normalize keys (without prefix):
<?php
function to_array_recursive($value): array
{
        if (!
is_object($value)) {
                return (array)
$value;
        }
       
$class = get_class($value);
       
$arr = [];
       
foreact ((array)  $value as $key => $val) {
               
$key = str_replace(["\0*\0", "\0{$class}\0"], '', $key);
               
$arr[$key] = is_object($val) ? to_array_recursive($val) : $val;
        }
        return
$arr;
}

function
to_array($value): array
{
       
$arr = (array) $value;
        if (!
is_object($value)) {
                return
$arr;
        }
       
$class = get_class($value);
       
$keys = str_replace(["\0*\0", "\0{$class}\0"], '', array_keys($arr));
        return
array_combine($keys, $arr);
}
?>
Demo:
<?php
class Test
{
        protected
$var = 1;
        protected
$var2;
        private
$TestVar = 3;
       
    public function
__construct($isParent = true)
    {
        if (
$isParent) {
           
$this->var2 = new self(! $isParent);
        }
    }
}

$obj = new Test();
var_dump((array) $obj, to_array_recursive($obj));
?>
up
-9
ivegner at yandex dot ru
10 years ago
Note that objects of classes extending ArrayObject SPL class are treated as arrays, and not as objects when converting to array.

<?php
class ArrayObjectExtended extends ArrayObject
{
    private
$private = 'private';
    public
$hello = 'world';
}

$object = new ArrayObjectExtended();
$array = (array) $object;

// This will not expose $private and $hello properties of $object,
// but return an empty array instead.
var_export($array);
?>
up
-14
Walter Tross
13 years ago
It is true that "array assignment always involves value copying", but the copy is a "lazy copy". This means that the data of the two variables occupy the same memory as long as no array element changes.

E.g., if you have to pass an array to a function that only needs to read it, there is no advantage at all in passing it by reference.
up
-27
gfr7oo at gmail dot com
4 years ago
<?php
function getArray() {
    return array(
1, 2, 3);
}

// on PHP 5.4
$secondElement = getArray()[1];

// previously
$tmp = getArray();
$secondElement = $tmp[1];

// or
list(, $secondElement) = getArray();
?>

Here list(, $secondElement) = getArray();
and list($secondElement) = getArray(); is the same thing
so you can avoid the "comma" to avoid the confusion.
To Top