+ opérateur pour tableau en PHP?

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

Que +signifie tableau en PHP?

user198729
la source
5
Je remarque que votre question avait +=et la réponse acceptée avait +. D'après mes tests, ils semblent se comporter de la même manière.
user151841
7
La documentation le résume assez bien
artfulrobot
1
duplication possible de Référence - Que signifie ce symbole en PHP?
Robbie Averill
@RobbieAverill - c'est la question à laquelle se réfère cette question de référence. Donc, si quelque chose de cette question de référence est le double
icc97
2
Quelqu'un d'autre est-il un peu horrifié qu'une chose aussi fondamentale que la concaténation de tableaux doive être effectuée array_merge? C'est comme si les tableaux étaient par défaut des tableaux associatifs et que les tableaux numériques étaient des citoyens de seconde classe.
icc97

Réponses:

271

Citant le manuel PHP sur les opérateurs de langage

L'opérateur + renvoie le tableau de droite ajouté au tableau de gauche; pour les clés qui existent dans les deux tableaux, les éléments du tableau de gauche seront utilisés et les éléments correspondants du tableau de droite seront ignorés.

Alors si tu fais

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

print_r($array1 + $array2);

Tu auras

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)
)

La logique de +équivaut donc à l'extrait de code suivant:

$union = $array1;

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

Si vous êtes intéressé par les détails de la mise en œuvre au niveau C, dirigez-vous vers


Notez que cela +est différent de la façon dont array_merge()combinerait les tableaux:

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

te donnerais

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
)

Voir les pages liées pour plus d'exemples.

Gordon
la source
1
@Pacerier PHP produit par php.net n'a pas de spécification formelle, mais à la fois l' appel +et sous le capot. Ceci est également attendu, car dans PHP, les tableaux sont implémentés sous forme de cartes de hachage ordonnées. array_mergezend_hash_merge
évêque
1
@Pacerier Les documents en ligne de php.net sont l'enregistrement le plus proche d'une spécification, mais IMO, ces documents sont loin d'une vraie spécification: premièrement, ils sont mis à jour après l'écriture du code; deux, ils ne sont pas écrits pour couvrir chaque utilisation spéciale.
évêque
14
Le comportement de PHP +et array_mergeest pervers et peu intuitif. Ils sont à l'opposé de ce qu'une lecture en anglais simple vous dirait intuitivement «d'ajouter» ou de «fusionner» des tableaux. D'autres langages / bibliothèques utilisent +pour concaténer des listes (par exemple en Python) et des fonctions de "fusion" pour ajouter les paires clé / valeur d'un objet à un autre (par exemple dans lodash). Pourtant, en PHP, c'est l'inverse; array_mergepeut être utilisé pour concaténer des tableaux de type liste mais +ne le peut pas. Contrairement à array_merge, +effectue toujours l'opération qui s'appellerait une "fusion" dans n'importe quelle autre langue.
Mark Amery
1
@ icc97 ce ne sont en effet que des HashMaps. Voir nikic.github.io/2014/12/22/…
Gordon
2
J'ai essayé de soumettre un bogue pour voir si un alias array_concatpouvait être créé pour array_merge.
icc97
18

Le meilleur exemple que j'ai trouvé pour l'utiliser est dans un tableau de configuration.

$user_vars = array("username"=>"John Doe");
$default_vars = array("username"=>"Unknown", "email"=>"[email protected]");

$config = $user_vars + $default_vars;

Le $default_vars, comme il le suggère, est le tableau des valeurs par défaut. Le $user_varstableau écrasera les valeurs définies dans $default_vars. Toutes les valeurs manquantes dans $user_varssont désormais les vars par défaut $default_vars.

Ce serait print_rcomme:

Array(2){
    "username" => "John Doe",
    "email" => "[email protected]"
}

J'espère que ça aide!

Frank de Jonge
la source
6

Cet opérateur prend l'union de deux tableaux (identique à array_merge, sauf qu'avec array_merge, les clés en double sont écrasées).

La documentation des opérateurs de tableau se trouve ici .

Peter Smit
la source
1
Un mot d'avertissement pour les débutants ici, le résultat de l'opération est nul si l'un des tableaux est nul . Certains pourraient ne pas se soucier de cela en supposant qu'il s'agit d'une opération d'union, le résultat sera le tableau approprié (non nul) si l'un d'entre eux est nul. Mais cela est vrai si l'un des tableaux est un tableau vide .
Sandeepan Nath
Donc, comme bonne pratique, je pense, nous devrions initialiser les tableaux d'entrée en tant que tableaux vides. Que dites-vous les gars?
Sandeepan Nath
5

Attention avec les touches numériques, si elles doivent être conservées ou si vous ne voulez rien perdre

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

syndicat

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

fusionner

print_r(array_merge($a, $b));
Array
(
    [0] => a2
    [1] => a4
    [2] => a5
    [3] => b1
    [4] => b3
    [5] => b4
)
décaillibaud
la source
3

L' +opérateur produit les mêmes résultats que array_replace () . Cependant, comme les arguments de l'opérateur sont inversés, l'ordre du tableau résultant peut également être différent.

Expansion sur un autre exemple de cette page:

$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

les sorties:

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
)
Tamlyn
la source
La commande est-elle +garantie par les spécifications? Et quoi array_replace?
Pacerier
1
  1. L'opération Array plus traite tous les tableaux comme des tableaux d'assoc.
  2. En cas de conflit de clé pendant plus, la valeur gauche (précédente) sera conservée

Je poste le code ci-dessous pour clarifier les choses.

$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
la source
L'exécution de code de @ Tamlyn semble prouver que votre affirmation "array plus operation traite tout le tableau comme un tableau assoc" est fausse.
Pacerier
@Pacerier cette clé pourrait également être un entier.
Hitesh
-2

Il ajoutera le nouveau tableau au précédent.

SorcyCat
la source
-4
$var1 = "example";
$var2 = "test";
$output = array_merge((array)$var1,(array)$var2);
print_r($output);

Array ([0] => exemple [1] => test)

Henning
la source
1
Ce fil mentionne à quelques reprises comment array_merge () n'est PAS congruente.
doublejosh
@doublejosh, "congruent"? Sens?
Pacerier
1
Ils ne sont pas les mêmes.
doublejosh