Php add to array with foreach

Modifying an array during a foreach loop [closed]

Questions must involve real code that you own or maintain. Pseudocode, hypothetical code, or stub code should be replaced by a concrete implementation. Questions seeking an explanation of someone else’s code are also off-topic.

This question is always on my mind. I usually alter the array while looping through its keys, based on my gut feelings:

foreach (array_keys($array) as $key)
foreach ($array as $key => $value)

What are the performance and security implications of each approach? Is there a recommended approach? UPDATE: What I’m actually worried about is that the two last approaches modify the array while I’m looping it.

\$\begingroup\$ OP gave actual code and yet it’s closed because the code is not part of a «concrete implementation»? honestly, what ? \$\endgroup\$

5 Answers 5

If you are worried about modifying the array while looping, don’t because foreach copies the array. Try

$array = array('foo'); foreach ($array as $k => &$item) < $array[] = 'bar'; >var_dump($array); 

And see it terminates just fine. foreach ($array as $k => &$v) is a shorthand for foreach (array_keys($array) as $k) $v = &$array[$k] so while there still is a copy of the array (that’s why I used &$item in my example so you can see, if you modify the array then it’ll be modified in the reference!

$array = array('foo', 'bar'); foreach ($array as $k => $item) < echo "$item\n"; if (!$k) < $array[1] = 'baz'; >> $array = array('foo', 'bar'); foreach ($array as $k => &$item) < echo "$item\n"; if (!$k) < $array[1] = 'baz'; >> 

the first dump foo and bar, the second foo and baz.

\$\begingroup\$ «foreach ($array as $k => $v) is a shorthand for foreach (array_keys($array) as $k) $v = &$array[$k]» On a very picky note, that’s not a shorthand as much as a difference in calling a function and a language construct (though for practical reasons, I suppose it’s a shorthand). Also, it would be shorthand for a copy, not a reference. (Also, PHP is copy-on-write, so you can typically ignore extra copies.) \$\endgroup\$

\$\begingroup\$ Obviously that wanted to be foreach ($array as $k => &$v) edited and fixed. \$\endgroup\$

\$\begingroup\$ Would like to point out that if(!$k) is TRUE for 0, otherwise this statement is always false. So essentially you are overwriting the second array element before ever seeing it. \$\endgroup\$

\$\begingroup\$ I do that and by doing that, I am demonstrating that the first foreach works from a copy and the second doesn’t. \$\endgroup\$

\$\begingroup\$ @chx You might want to run your first snippet then. $item is a copy of a value from $array. $array is never copied (though all elements of $array will be copied if the foreach loop completes). The first snippet will dump foo and baz just like the second one. \$\endgroup\$

Читайте также:  Java rmi server port already in use

This sounds like a place for array_map() .

$array = array_map('perform_changes_on', $array); 

\$\begingroup\$ nice, but sometimes i won’t change every item in the array. I just tried to make the example simpler. \$\endgroup\$

\$\begingroup\$ perfom_changes_on doesn’t have to change every element. Note that there are other array functions, some more powerful than others. array_reduce can help a lot, for example. \$\endgroup\$

\$\begingroup\$ Doesn’t this involve a function call for every element? May not be the best performance wise. \$\endgroup\$

\$\begingroup\$ @Tom: I wouldn’t say the overhead of function call is notable. Maintainability is way more important than very small performance gains (that I’m not even sure if they even do exist). But if you think that writing 100,000 lines program without functions is a best way of programming, by all means do it. Just don’t be surprised when nobody wants to maintain the code, and you won’t understand what you wrote a day later. \$\endgroup\$

When using foreach($array as &$item) never ever forget the unset($item); after the foreach or you will get into serious trouble trying to use $item later. It should be habitual to avoid this trap.

In general you should avoid foreach . & and do array_walk($array, function (&$item) <. so that the reference is strictly confined inside the closure.

\$\begingroup\$ thanks for the answer, I’m using array_keys to avoid the trap, but do I need to use it? I mean, foreach ($array as $key => $item) should let me change $array[$key] value, but who knows how php works internally. that’s the question, actually. \$\endgroup\$

I can’t really help you with the performance bit, only tell you to wrap them in microtime() tags and see which one performs better for you. Systems are slightly different. The one suggestion I can give you is to remove array_keys() from your code.

If you were following Corbin and my argument below, then I finally have an answer for you. I was getting for and foreach confused. For and while loops do call any functions passed in as arguments on every iteration, foreach does not. Which is why its better to call functions such as strlen() and count() , just to give a couple of examples, outside of a for or while loop. The overhead we were experiencing was not from foreach but from array_keys() . When array_keys() is called it must generate a new array, which is why it is almost twice as slow. So it is best to drop the array_keys() function all-together and just iterate over the array and retrieve the key value pair. Sorry for any confusion this may have caused.

!!END OF UPDATE!!

To the best of my knowledge there is no security risk with any of those implementations. You are iterating a construct that already exists. Any security issues would have happened before this point. Except of course if you are using user supplied data, such as GET and POST. These you should sanitize and validate before using, which is something you could do with one of those foreach loops. Or you could also check out filter_input_array() and its cousins.

Читайте также:  Html css vertical centering

I know I personally would not use the second implementation due to the lack of legibility. At least with the first and third implementations you can visually see that a value is being changed. The second is not readily obvious. However, it is most likely the more efficient. I have used both the first and third myself, but more often use the third. Think it has to do with what mood I’m in. Hope this helps, I’m interested to hear what others might have to say 🙂

Источник

Add Array to Array in PHP

Add Array to Array in PHP

  1. Using the for and foreach Loops to Add Array to Array in PHP
  2. Using the array_merge() Function to Add Array to Array in PHP
  3. Using the array_push() Function to Add Array to Array in PHP

Arrays contain a series of indexed elements of the same data type, often for faster iteration and data management.

Typically, to access array elements, you will loop over the array. For example, in a PHP application, an array could hold data from the registration form, and another array could hold data from the account details section. To use both arrays in one sequence, we need to add both arrays. To achieve this, we need to append the second array to the first, and different functions behave differently.

This tutorial discusses the different methods to add two arrays together to form one array in PHP.

Using the for and foreach Loops to Add Array to Array in PHP

A simple method to add an array to another array is to select the second array, loop through all the elements, and append each element to the first array. However, this particular solution is rather long and inefficient for larger arrays.

$container = ["hair extension", "scissors"]; $shopping_lists = ["hair cream", "hair fryer", "makeup set"]; for($index = 0; $index  count($shopping_lists ); $index++)  array_push($container, $shopping_lists[$index]); > print_r($container) 
Array (  [0] hair extension  [1] scissors  [2] hair cream  [3] hair fryer  [4] makeup set )  true 

Also, you can apply the same approach to an associative array. However, it comes with the same inefficiency and complexity.

$customer = array(  "name" => "Garner",  "email" => "g.abded@gmail.com",  "age" => 34,  "gender" => "female",  "account_type" => "starter" );  $account = array(  "current_course" => "Ruby Crash Course",  "payment_channel" => "Stripe",  "browser" => "Edge" );  foreach($account as $key => $value)   $customer[$key] = $value; >  print_r($customer) 
Array (  [name] Garner  [email] g.abded@gmail.com  [age] 34  [gender] female  [account_type] starter  [current_course] Ruby Crash Course  [payment_channel] Stripe  [browser] Edge )  true 

Using the array_merge() Function to Add Array to Array in PHP

The array_merge() function merges two or more arrays and appends the elements of one array to the end of the previous array, and so on, till the last array. This function works for index, associative and multidimensional arrays. Unlike the previous method, this approach creates a new array and does not append to the first array.

This method can work with multiple arrays. In more detail, we can use this approach to add the key-value pair (associative arrays) to one another to form one single array. The same goes for index arrays.

$details = [  "name" => "Clement",  "email" => "clement@gmail.com",  "gender" => "male" ];  $accounts = [  "card" => "mastercard",  "processor" => "stripe",  "pro" => True ];  $account_details = array_merge($details, $accounts);  print_r($account_details); 
Array (  [name] Clement  [email] clement@gmail.com  [gender] male  [card] mastercard  [processor] stripe  [pro] 1 )  true 

Here is how to use the array_merge() function on three arrays.

$details = [  "name" => "Clement",  "email" => "clement@gmail.com",  "gender" => "male" ]; $accounts = [  "card" => "mastercard",  "processor" => "stripe",  "pro" => True ]; $functions = [  "movies" => "inferno" ]; $account_details = array_merge($details, $accounts, $functions); print_r($account_details); 
Array (  [name] Clement  [email] clement@gmail.com  [gender] male  [card] mastercard  [processor] stripe  [pro] 1  [movies] inferno )  true 

This method is compatible with all PHP 7.0 versions and above.

Using the array_push() Function to Add Array to Array in PHP

The array_push() function pushes the array(s) onto the end of the array like a stack (LIFO). You can use this function to add an index array to an associative array, and it will automatically create a numerical index for the index array pushed to the associative array. If two index arrays are pushed, the first index array holds the numerical index of 0, and the second index array holds the numerical index of 1. For N arrays pushed, the numerical index will be N-1 .

Additionally, you can push index arrays to an index array and associative arrays to an associative array.

$basic_data = ['Location' => 'Mumbai', 'Tier' => 'Three']; $tools = ['Geology', 'Machine Learning']; $BD_Tools = array_push($basic_data, $tools);  print_r($basic_data); 
Array (  [Location] Mumbai  [Tier] Three  [0] Array  (  [0] Geology  [1] Machine Learning  ) )  true 

In addition, use the . operator within the array_push() function to allow all the elements within the pushed array(s) to have their own numerical index rather than one for all.

$basic_data = ['Location' => 'Mumbai', 'Tier' => 'Three']; $tools = ['Geology', 'Machine Learning']; $BD_Tools = array_push($basic_data, . $tools);  print_r($basic_data); 
Array (  [Location] Mumbai  [Tier] Three  [0] Geology  [1] Machine Learning )  true 

For associative array push operations, you can’t use the . operator, as it will throw an error.

TypeError: array_push() does not accept unknown named parameters null 

Therefore, the only way to use array_push() function with two or more arrays is via the default means.

$basic_data = ['Location' => 'Mumbai', 'Tier' => 'Three']; $tools = ['Course' => 'Geology', 'Approach' => 'Machine Learning']; $BD_Tools = array_push($basic_data, $tools);  print_r($basic_data); 
Array (  [Location] Mumbai  [Tier] Three  [0] Array  (  [Course] Geology  [Approach] Machine Learning  )  )  true 

Olorunfemi is a lover of technology and computers. In addition, I write technology and coding content for developers and hobbyists. When not working, I learn to design, among other things.

Источник

Оцените статью