2

I have

$products = array(
        "product1" => [
            "a" => ["total" => 1],
            "b" => ["total" => 3],
            "c" => ["total" => 2],
        ],
        "product2" => [
            "d" => ["total" => 3],
            "f" => ["total" => 2],
            "e" => ["total" => 1],
        ],
        "product3" => [
            "g" => ["total" => 3]
        ],
    );

theses are my products and my stocks for each warehouses (warehouse a has 1 item of product1...)

I want to sort each warehouse by stock for each products. I've done that :

foreach ($products as &$stocks) {
        uasort($stocks, function($elmt1, $elmt2) {
            return $elmt2["total"] - $elmt1["total"];
        });
}

where I print my new array :

array(3) {
  ["product1"]=>
  array(3) {
    ["b"]=>
    array(1) {
      ["total"]=>
      int(3)
    }
    ["c"]=>
    array(1) {
      ["total"]=>
      int(2)
    }
    ["a"]=>
    array(1) {
      ["total"]=>
      int(1)
    }
  }
  ["product2"]=>
  array(3) {
    ["d"]=>
    array(1) {
      ["total"]=>
      int(3)
    }
    ["f"]=>
    array(1) {
      ["total"]=>
      int(2)
    }
    ["e"]=>
    array(1) {
      ["total"]=>
      int(1)
    }
  }
  ["product3"]=>
  &array(1) {
    ["g"]=>
    array(1) {
      ["total"]=>
      int(3)
    }
  }
}

It did my job but when I get a closer look I can see the "&" char in only one of the arrays.

Why ?

d3cima
  • 729
  • 1
  • 10
  • 31

1 Answers1

1

Due to the fact that $item - a reference to the last element of the array. You can do this trick:

$array = ['a', 'b', 'c'];
foreach ($array as &$item) {

}
foreach ($array as $item) {
    $item = 1;
}

var_dump($array);

Output:

array(3) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  &int(1)
}

It's not terrible, as long as you do not start to use $item. It is better to make a job with reference in different function

$array = ['a', 'b', 'c'];
$test = function () use (&$array) {
    foreach ($array as &$item) {
    }
};
$test();
var_dump($array);

Output:

array(3) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [2]=>
  string(1) "c"
}

Or try this:

$products = array(
    "product1" => [
        "a" => ["total" => 1],
        "b" => ["total" => 3],
        "c" => ["total" => 2],
    ],
    "product2" => [
        "d" => ["total" => 3],
        "f" => ["total" => 2],
        "e" => ["total" => 1],
    ],
    "product3" => [
        "g" => ["total" => 3]
    ],
);

foreach ($products as $key=>$stocks) {
    uasort($products[$key], function($elmt1, $elmt2) {
        return $elmt2["total"] - $elmt1["total"];
    });
}

var_dump($products);

Output:

array(3) {
  ["product1"]=>
  array(3) {
    ["b"]=>
    array(1) {
      ["total"]=>
      int(3)
    }
    ["c"]=>
    array(1) {
      ["total"]=>
      int(2)
    }
    ["a"]=>
    array(1) {
      ["total"]=>
      int(1)
    }
  }
  ["product2"]=>
  array(3) {
    ["d"]=>
    array(1) {
      ["total"]=>
      int(3)
    }
    ["f"]=>
    array(1) {
      ["total"]=>
      int(2)
    }
    ["e"]=>
    array(1) {
      ["total"]=>
      int(1)
    }
  }
  ["product3"]=>
  array(1) {
    ["g"]=>
    array(1) {
      ["total"]=>
      int(3)
    }
  }
}
Maxim Tkach
  • 1,607
  • 12
  • 23