Операторы для работы с массивами в PHP

Написана 30 Июня, 2013 в 21:25. Автор: borN_free   |   Теги: php, array, operator Комментарии 0

PHP Array Operators

Вольный перевод статьи Array Operators in PHP: Interesting but Less Spoken




Операторы в PHP можно разбить на следующие категории:

  • арифметические
  • присваивания
  • битовые
  • сравнения
  • контроля ошибок
  • выполнения
  • инкремента/декремента
  • логические
  • строковые
  • массивов
  • операторы типов

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

Операторы для работы с массивами

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

Объединение (Array Union)

Первый оператор - объединение (+). Объединение двух массивов работает по ключам. Все ключи второго массива игнорируются, если в первом содержатся эквивалентные ключи.

$array1 = array('a', 'b', 'c');
$array2 = array('d', 'e', 'f', 'g', 'h', 'i');
print_r($array1 + $array2);
print_r($array2 + $array1);
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => g
    [4] => h
    [5] => i
)
Array
(
    [0] => d
    [1] => e
    [2] => f
    [3] => g
    [4] => h
    [5] => i
)

В первом случае print_r() (строка 4), первые три элемента в $array2 имеют ключи, которые уже содержатся в $array1, таким образом 'd', 'e' и 'f' игнорируются в результирующем массиве. В втором случае print_r() (строка 5), все ключи массива $array1 уже существуют в массиве $array2, поэтому все элементы $array1 игнорируются.

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

$array1 = array('0' => 'a', '1' => 'b', '2' => 'c', '3' => 'd');
$array2 = array(false => 'e', 1 => 'f', 2 => 'g', 3 => 'h', 4 => 'i');
print_r($array1 + $array2);
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
    [4] => i
)

Существует ошибочное понимание того, что объединение происходит по значениям массива, в то время как оно происходит по ключам массива. Для того, чтобы объединить массивы по значениям, вы можете использовать array_merge() и array_unique():

$union = array_unique(array_merge($array1, $array2));
print_r($union);
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
    [4] => e
    [5] => f
    [6] => g
    [7] => h
    [8] => i
)

Равенство массивов (Array Equality)

Оператор равенства (==) проверяет похожи ли массивы. Он возвращает true, если все пары ключ-значение в первом массиве эквиваленты парам ключ-значение во втором массиве. Он нестрого проверяет значения и ключи, а последовательность элементов не играет роли.

$array1 = array('1' => 1, '2' => 2, '3' => 3, '0' => 0);
$array2 = array(false => '0', 1 => '1', 2 => '2', 3 => '3');
var_dump($array1 == $array2);
bool(true)

Последовательность элементов в двух массивах различна, но одинаковые значения связаны с одинаковыми ключами в каждом из массивов. Однако, следующие два массива не эквивалентны, потому что каждые из них содержат различные пару ключ-значение:

$array1 = array(1, 2);
$array2 = array(2, 1);
var_dump($array1 == $array2);
bool(false)

Оператор неравенства (!= или <>) проверяет, не похожи ли два массива, и является полной противоположностью оператора равенства. Все, для чего оператор равенства возвращает false, оператор неравенства вернет true, и наоборот.

$array1 = array('1' => 1, '2' => 2, '3' => 3, '0' => 0);
$array2 = array(false => '0', 1 => '1', 2 => '2', 3 => '3');
var_dump($array1 != $array2);
bool(false)

Идентичность массивов (Array Identity)

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

  • имеют одно и то же количество элементов
  • имеют одинаковые пары ключ-значение
  • имеют одинаковую последовательность элементов
  • имеют один и тот же тип соответствующих элементов

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

// массивы практически идентичны, но типы ключей не совпадают
$array1 = array('0' => '0', '1' => '1', '2' => '2', '3' => '3');
$array2 = array(0 => '0', 1 => '1', 2 => '2', 3 => '3');
var_dump($array1 === $array2);
bool(true)
// последовательность элементов в двух массивах не идентична
$array1 = array('0' => '0', '1' => '1', '2' => '2', '3' => '3');
$array2 = array(1 => '1', 2 => '2', 3 => '3', 0 => '0');
var_dump($array1 === $array2);
bool(false)
// ключ в первом массиве - строка, во втором - число типа float
$array1 = array('0.5' => '0');
$array2 = array(0.5 => '0');
var_dump($array1 === $array2);
bool(false)

Для оператора неидентичности все очевидно (работает противоположно оператору идентичности).

$array1 = array('0' => '0', '1' => '1', '2' => '2', '3' => '3');
$array2 = array(0 => '0', 1 => '1', 2 => '2', 3 => '3');
var_dump($array1 !== $array2);
bool(false)

Использование массивов с другими операторами

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

Фатальная ошибка. (Fatal Error. Unexpected Operand Type)

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

  • оператор побитовое НЕ (~)
  • арифметическое отрицание (-)
  • арифмитическое вычитание (-)
  • арифметическое умножение (*)
  • арифметическое деление (/)

Массивы обращаются в целые числа

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

  • Логическое НЕ (!) возвращает true для пустых массивов и false, когда массив имеет 1 или более элементов.
  • Побитовое И (&) возвращает 1 если оба массива непустые и 0, когда один или оба пустые.
  • Побитовое ИЛИ (|) возвращает 0 если оба массива пусты, иначе 1.
  • Побитовое исключающее ИЛИ (^) возвращает 0 если оба сразу либо пусты, либо нет. Если только один из двух пустой массив, возвращает 1.
  • Сдвиг массива влево на n позиций с помощью оператора (<<) возвращает рузельтат, эквивалентный 1 << n, если массив непустой, иначе возвращает 0 (0 << n).
  • Точно такое же поведение, как и в предыдущем случае, только сдвиг правый.
  • Оператор % возвращает true, если оба массива непустые. Если второй массив пустой, происходит ошибка "деление на ноль". Если правый пустой - возвращается ноль (0 % 1).
  • Логические И (&& или AND) возвращает false, если любой из массивов пустой. Если оба не пусты, возвращает true.
  • Логическое ИЛИ (|| или OR) возвращает true, если хотябы один массив не пустой. Возвращает false, если оба пусты.
  • Логическое исключающее ИЛИ (XOR) возвращает false, если оба массива одновременно либо пусты, либо нет. Если только один из двух пустой массив, возвращает true.
  • Приведение массива к типу bool возвращает false, если массив пустой, иначе true.

Массивы обращаются в строки

Когда конкатенируются два массива, оператор конкатенации (.) берет каждый массив как строку 'Array' и соединяет их.

$array1 = array(0, 1, 2, 3);
$array1 = array(0, 1, 2, 3);
var_dump($array1 . $array2);
string(10) "ArrayArray"

Операторы, не влияющие на массивы

Инкремент/декремент массива не влияют на него:

$array1 = $array2;
var_dump((++$array1) === $array2);
bool(true)

Оставьте свой комментарий:

Поля с * обязательны.