+ оператор для массива в PHP?

197
$test = array('hi');
$test += array('test','oh');
var_dump($test);

Что +означает массив в PHP?

user198729
источник
5
Я заметил, что у вашего вопроса был +=и принятый ответ +. Судя по моему тестированию, они ведут себя одинаково.
user151841
7
Документации подводит итог довольно хорошо
artfulrobot
1
возможный дубликат ссылки - что означает этот символ в PHP?
Робби Аверилл
@RobbieAverill - это вопрос, к которому относится этот справочный вопрос. Так что, во всяком случае, этот справочный вопрос является дубликатом
icc97
2
Кто-нибудь еще немного напуган тем, что такая фундаментальная вещь, как конкатенация массивов, должна быть выполнена array_merge? Это как если бы массивы по умолчанию были ассоциативными массивами, а числовые массивы - гражданами второго сорта.
icc97

Ответы:

277

Цитата из руководства PHP по операторам языка

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

Итак, если вы это сделаете

$array1 = ['one',   'two',          'foo' => 'bar'];
$array2 = ['three', 'four', 'five', 'foo' => 'baz']; 

print_r($array1 + $array2);

Ты получишь

Array
(
    [0] => one   // preserved from $array1 (left-hand array)
    [1] => two   // preserved from $array1 (left-hand array)
    [foo] => bar // preserved from $array1 (left-hand array)
    [2] => five  // added from $array2 (right-hand array)
)

Таким образом, логика +эквивалентна следующему фрагменту:

$union = $array1;

foreach ($array2 as $key => $value) {
    if (false === array_key_exists($key, $union)) {
        $union[$key] = $value;
    }
}

Если вас интересуют подробности реализации C-уровня, обратитесь к


Обратите внимание, что +это отличается от того, как array_merge()объединить массивы:

print_r(array_merge($array1, $array2));

дал бы вам

Array
(
    [0] => one   // preserved from $array1
    [1] => two   // preserved from $array1
    [foo] => baz // overwritten from $array2
    [2] => three // appended from $array2
    [3] => four  // appended from $array2
    [4] => five  // appended from $array2
)

Дополнительные примеры см. На связанных страницах.

Гордон
источник
1
@Pacerier PHP, созданный php.net, не имеет формальной спецификации, но оба вызова +и находятся под капотом. Это также ожидается, поскольку в PHP массивы реализованы в виде упорядоченных хэш-карт. array_mergezend_hash_merge
епископ
1
@Pacerier Онлайн-документы php.net - это самая близкая запись к спецификации, но IMO эти документы не соответствуют истинной спецификации: во-первых, они обновляются после написания кода; во-вторых, они написаны не для каждого специального использования.
епископ
16
Поведение PHP +и array_mergeявляется извращенным и неинтуитивным. Они противоположны тому, что при чтении на простом английском языке интуитивно подсказывает вам «добавление» или «слияние» массивов. Другие языки / библиотеки используются +для объединения списков (например, в Python) и функций «слияния» для добавления пар ключ / значение из одного объекта в другой (например, в lodash). Однако в PHP все наоборот; array_mergeможет использоваться для объединения массивов, подобных списку, но +не может. В отличие от array_merge, +всегда выполняет операцию, которую на любом другом языке назвали бы «слиянием».
Марк Эмери,
1
@ icc97, это действительно только HashMaps. См. Nikic.github.io/2014/12/22/…
Гордон
2
Я попытался подав ошибку , чтобы увидеть , если псевдоним array_concatможет быть создан array_merge.
icc97
19

Лучший пример, который я нашел для этого, - это массив конфигурации.

$user_vars = array("username"=>"John Doe");
$default_vars = array("username"=>"Unknown", "email"=>"no-reply@domain.com");

$config = $user_vars + $default_vars;

Как $default_varsпредполагается, это массив значений по умолчанию. $user_varsМассив будет перезаписать значения , определенные в $default_vars. Любые отсутствующие значения в $user_varsтеперь являются значениями по умолчанию $default_vars.

Это было бы print_rтак:

Array(2){
    "username" => "John Doe",
    "email" => "no-reply@domain.com"
}

Надеюсь, это поможет!

Франк де Йонге
источник
6

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

Документацию по операторам массива можно найти здесь .

Питер Смит
источник
1
Предупреждение для новичков: результат операции равен нулю, если какой-либо из массивов равен нулю . Некоторые могут не заботиться об этом, предполагая, что, поскольку это операция объединения, результатом будет правильный (не нулевой) массив, если один из них имеет значение NULL. Но это верно, если один из массивов является пустым .
Sandeepan Nath
Поэтому я считаю хорошей практикой инициализировать входные массивы как пустые. Что вы скажете, ребята?
Sandeepan Nath
5

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

$a = array(2 => "a2", 4 => "a4", 5 => "a5");
$b = array(1 => "b1", 3 => "b3", 4 => "b4");

союз

print_r($a+$b);
Array
(
    [2] => a2
    [4] => a4
    [5] => a5
    [1] => b1
    [3] => b3
)

слияние

print_r(array_merge($a, $b));
Array
(
    [0] => a2
    [1] => a4
    [2] => a5
    [3] => b1
    [4] => b3
    [5] => b4
)
Dcaillibaud
источник
3

+Оператор производит одни и те же результаты , как array_replace () . Однако, поскольку аргументы оператора меняются местами, порядок результирующего массива также может быть другим.

Расширяя еще один пример с этой страницы:

$array1 = array('one', 'two', 'foo' => 'bar');
$array2 = array('three', 'four', 'five', 'foo' => 'baz'); 

print_r($array1 + $array2);
print_r(array_replace($array2, $array1)); //note reversed argument order

выходы:

Array
(
    [0] => one   // preserved from $array1
    [1] => two   // preserved from $array1
    [foo] => bar // preserved from $array1
    [2] => five  // added from $array2
)
Array
(
    [0] => one   // preserved from $array1
    [1] => two   // preserved from $array1
    [2] => five  // added from $array2
    [foo] => bar // preserved from $array1
)
Тамлин
источник
+Гарантирован ли порядок спецификациями? О чем array_replace?
Pacerier
1
  1. Операция «Массив плюс» обрабатывает весь массив как связанный массив.
  2. При конфликте клавиш во время плюса, левое (предыдущее) значение будет сохранено

Я размещаю код ниже, чтобы прояснить ситуацию.

$a + $b = array_plus($a, $b)

function array_plus($a, $b){
    $results = array();
    foreach($a as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
    foreach($b as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
    return $results;
}
Gucci Koo
источник
Выполнение кода @ Tamlyn, кажется, доказывает, что ваше утверждение "массив плюс операция обрабатывает весь массив как ассоциативный массив" неверно.
Pacerier
@Pacerier, этот ключ также может быть целым числом.
Hitesh
-2

Он добавит новый массив к предыдущему.

SorcyCat
источник
-4
$var1 = "example";
$var2 = "test";
$output = array_merge((array)$var1,(array)$var2);
print_r($output);

Массив ([0] => пример [1] => тест)

Хеннинг
источник
1
В этом потоке несколько раз упоминается, что array_merge () НЕ конгруэнтно.
doublejosh
@doublejosh, "конгруэнтный"? Имея в виду?
Pacerier
1
Они не то же самое.
doublejosh