114

I want to generate a selectbox using two arrays, one containing the country codes and another containing the country names.

This is an example:

$codes = ['tn', 'us', 'fr']; $names = ['Tunisia', 'United States', 'France']; foreach( $codes as $code and $names as $name ) { echo '<option value="' . $code . '">' . $name . '</option>'; } 

This method didn't work for me. Any suggestions?

1
  • two arrays one loop Commented Dec 10, 2021 at 15:53

26 Answers 26

177
foreach( $codes as $code and $names as $name ) { } 

That is not valid.

You probably want something like this...

foreach( $codes as $index => $code ) { echo '<option value="' . $code . '">' . $names[$index] . '</option>'; } 

Alternatively, it'd be much easier to make the codes the key of your $names array...

$names = array( 'tn' => 'Tunisia', 'us' => 'United States', ... ); 
Sign up to request clarification or add additional context in comments.

2 Comments

useful in parsing form field arrays.
avoid starting your answer with non-functional code only to say later that it doesn't work. A negative statement should be prefaced as negative when it spans multiple paragraphs
98

foreach operates on only one array at a time.

The way your array is structured, you can array_combine() them into an array of key-value pairs then foreach that single array:

foreach (array_combine($codes, $names) as $code => $name) { echo '<option value="' . $code . '">' . $name . '</option>'; } 

Or as seen in the other answers, you can hardcode an associative array instead.

6 Comments

Can this also be used for three arrays?
@xjshiya No, if you give them 3 parameters you get Warning: array_combine() expects exactly 2 parameters, 3 given
@xjshiya You could do array_combine($arr1, array_combine($arr2, $arr3))
That only works for string and int values, it won't work for objects, booleans and other arrays.
And it doesn't work for arrays that are already associative.
|
29

Use array_combine() to fuse the arrays together and iterate over the result.

$countries = array_combine($codes, $names); 

2 Comments

That only works for string and int values, it won't work for objects, booleans and other arrays.
Using array_combine() may not be suitable if the values which become keys are not compatible or become mutated when used as array keys.
9

array_map seems good for this too

$codes = array('tn','us','fr'); $names = array('Tunisia','United States','France'); array_map(function ($code, $name) { echo '<option value="' . $code . '">' . $name . '</option>'; }, $codes, $names); 

Other benefits are:

  • If one array is shorter than the other, the callback receive null values to fill in the gap.

  • You can use more than 2 arrays to iterate through.

4 Comments

array_map() is appropriate when its return value is accessed. When the return data is unneeded, array_walk() is more appropriate.
Hi, true for the return functionality, though array_walk() doesn't accept more than one array (to iterate on each element of the 2 arrays at the same time), you may use its 3rd argument $arg, but you will get the whole array in each iteration instead of each of its elements.
A simple foreach() would also be more appropriate when no return value is sought.
array_walk() is certainly a viable tool for this task as demonstrated by @oLinkWebDevelopment's answer from back in 2014.
6

Use an associative array:

$code_names = array( 'tn' => 'Tunisia', 'us' => 'United States', 'fr' => 'France'); foreach($code_names as $code => $name) { //... } 

I believe that using an associative array is the most sensible approach as opposed to using array_combine() because once you have an associative array, you can simply use array_keys() or array_values() to get exactly the same array you had before.

3 Comments

+1 array_combine() already produces an associative array, you may want to be clearer about initializing it as associative.
That only works for string and int values, it won't work for objects, booleans and other arrays.
Further to Danon's comment, this is also not stable when the keys contain: null or float values.
4

This worked for me:

$codes = array('tn', 'us', 'fr'); $names = array('Tunisia', 'United States', 'France'); foreach($codes as $key => $value) { echo "Code is: " . $codes[$key] . " - " . "and Name: " . $names[$key] . "<br>"; } 

1 Comment

This is a worse copy of the accepted answer -- $value is simpler to use than $codes[$key].
4

Your code like this is incorrect as foreach only for single array:

<?php $codes = array('tn','us','fr'); $names = array('Tunisia','United States','France'); foreach( $codes as $code and $names as $name ) { echo '<option value="' . $code . '">' . $name . '</option>'; } ?> 

Alternative, Change to this:

<?php $codes = array('tn','us','fr'); $names = array('Tunisia','United States','France'); $count = 0; foreach($codes as $code) { echo '<option value="' . $code . '">' . $names[count] . '</option>'; $count++; } ?> 

Comments

3

Walk it out...

$codes = array('tn','us','fr'); $names = array('Tunisia','United States','France'); 
  • PHP 5.3+

    array_walk($codes, function ($code,$key) use ($names) { echo '<option value="' . $code . '">' . $names[$key] . '</option>'; }); 
  • Before PHP 5.3

    array_walk($codes, function ($code,$key,$names){ echo '<option value="' . $code . '">' . $names[$key] . '</option>'; },$names); 
  • or combine

    array_walk(array_combine($codes,$names), function ($name,$code){ echo '<option value="' . $code . '">' . $name . '</option>'; }) 
  • in select

    array_walk(array_combine($codes,$names), function ($name,$code){ @$opts = '<option value="' . $code . '">' . $name . '</option>'; }) echo "<select>$opts</select>"; 

demo

1 Comment

Using array_combine() may not be suitable if the values which become keys are not compatible or become mutated when used as array keys.
2

Why not just consolidate into a multi-dimensional associative array? Seems like you are going about this wrong:

$codes = array('tn','us','fr'); $names = array('Tunisia','United States','France'); 

becomes:

$dropdown = array('tn' => 'Tunisia', 'us' => 'United States', 'fr' => 'France'); 

3 Comments

It's called an associative array, not a multidimensional array.
That only works for string and int values, it won't work for objects, booleans and other arrays.
Using array_combine() may not be suitable if the values which become keys are not compatible or become mutated when used as array keys.
2

All fully tested

3 ways to create a dynamic dropdown from an array.

This will create a dropdown menu from an array and automatically assign its respective value.

Method #1 (Normal Array)

<?php $names = array('tn'=>'Tunisia','us'=>'United States','fr'=>'France'); echo '<select name="countries">'; foreach($names AS $let=>$word){ echo '<option value="'.$let.'">'.$word.'</option>'; } echo '</select>'; ?> 


Method #2 (Normal Array)

<select name="countries"> <?php $countries = array('tn'=> "Tunisia", "us"=>'United States',"fr"=>'France'); foreach($countries as $select=>$country_name){ echo '<option value="' . $select . '">' . $country_name . '</option>'; } ?> </select> 


Method #3 (Associative Array)

<?php $my_array = array( 'tn' => 'Tunisia', 'us' => 'United States', 'fr' => 'France' ); echo '<select name="countries">'; echo '<option value="none">Select...</option>'; foreach ($my_array as $k => $v) { echo '<option value="' . $k . '">' . $v . '</option>'; } echo '</select>'; ?> 

3 Comments

hm... downvote uncalled for. Downvoter, reason and care to elaborate? Obviously done "just cuz". Meh~
Aren't these all the same thing? I don't see any significant differences other than the names of the variables.
Using associative values limits the number of arrays iterated to 2. If the array of values used as keys contains values which are incompatible or mutated by PHP, then this approach is unsuitable.
1

You can use array_merge to combine two arrays and then iterate over them.

$array1 = array("foo" => "bar"); $array2 = array("hello" => "world"); $both_arrays = array_merge((array)$array1, (array)$array2); print_r($both_arrays); 

1 Comment

This doesn't appear to have any relationship to the asked question.
1

array_combine() worked great for me while combining $_POST multiple values from multiple form inputs in an attempt to update products quantities in a shopping cart.

1 Comment

Using array_combine() may not be suitable if the values which become keys are not compatible or become mutated when used as array keys.
1
<?php $codes = array ('tn','us','fr'); $names = array ('Tunisia','United States','France'); echo '<table>'; foreach(array_keys($codes) as $i) { echo '<tr><td>'; echo ($i + 1); echo '</td><td>'; echo $codes[$i]; echo '</td><td>'; echo $names[$i]; echo '</td></tr>'; } echo '</table>'; ?> 

1 Comment

This unexplained snippet makes an unnecessary call (array_keys()) then needs to use the $i variable to access each element from both arrays -- this is not the most elegant approach.
1

foreach only works with a single array. To step through multiple arrays, it's better to use the each() function in a while loop:

while(($code = each($codes)) && ($name = each($names))) { echo '<option value="' . $code['value'] . '">' . $name['value'] . '</option>'; } 

each() returns information about the current key and value of the array and increments the internal pointer by one, or returns false if it has reached the end of the array. This code would not be dependent upon the two arrays having identical keys or having the same sort of elements. The loop terminates when one of the two arrays is finished.

1 Comment

Too bad! This was perfect but deprecated from php 7 and removed from php 8.
1

Instead of foreach loop, try this (only when your arrays have same length).

$number = COUNT($_POST["codes "]);//count how many arrays available if($number > 0) { for($i=0; $i<$number; $i++)//loop thru each arrays { $codes =$_POST['codes'][$i]; $names =$_POST['names'][$i]; //ur code in here } } 

1 Comment

Using a foreach() means that you don't have to count the array and maintain a counter variable. A foreach() will not be entered if the count is 0.
1

i gave a simple example

 class Parallel implements Iterator { private int $index; private array $arrays; private int $countAny; public function __construct(array ...$arrays) { $this->countAny = count($arrays[0]); $this->arrays = $arrays; } #[\Override] public function current(): array { $return = []; foreach ($this->arrays as $array) { $return[] = $array[$this->index]; } return $return; } #[\Override] public function next(): void { $this->index++; } #[\Override] public function key(): mixed { return $this->index; } #[\Override] public function valid(): bool { return $this->index < $this->countAny; } #[\Override] public function rewind(): void { $this->index = 0; } } $parallel = new Parallel( [1, 2, 3, 4], ['a', 'b', 'c', 'd'], ['london', 'paris', 'rome', 'istanbul'], ); foreach ($parallel as [$number, $word, $city]) { echo PHP_EOL; printf('Number: %s, Word: %s, City: %s', $number, $word, $city); } 

4 Comments

Where is the educational explanation with this snippet dump?
Why should someone use tens of lines of code to do what the accepted answer can do in 3???
just for the reusable
Please edit this answer to make it educational.
0

I solved a problem like yours by this way:

foreach(array_keys($idarr) as $i) { echo "Student ID: ".$idarr[$i]."<br />"; echo "Present: ".$presentarr[$i]."<br />"; echo "Reason: ".$reasonarr[$i]."<br />"; echo "Mark: ".$markarr[$i]."<br />"; } 

1 Comment

This unexplained snippet makes an unnecessary call (array_keys()) then needs to use the $i variable to access each element from both arrays -- this is not the most elegant approach.
0

You should try this for the putting 2 array in singlr foreach loop Suppose i have 2 Array 1.$item_nm 2.$item_qty

 `<?php $i=1; ?> <table><tr><td>Sr.No</td> <td>item_nm</td> <td>item_qty</td> </tr> @foreach (array_combine($item_nm, $item_qty) as $item_nm => $item_qty) <tr> <td> $i++ </td> <td> $item_nm </td> <td> $item_qty </td> </tr></table> @endforeach ` 

1 Comment

Using array_combine() may not be suitable if the values which become keys are not compatible or become mutated when used as array keys.
0

I think that you can do something like:

$codes = array('tn','us','fr');

$names = array('Tunisia','United States','France');

foreach ($codes as $key => $code) { echo '<option value="' . $code . '">' . $names[$key] . '</option>'; } 

It should also work for associative arrays.

Comments

0

I think the simplest way is just to use the for loop this way:

$codes = array('tn','us','fr'); $names = array('Tunisia','United States','France'); for($i = 0; $i < sizeof($codes); $i++){ echo '<option value="' . $codes[$i] . '">' . $names[$i] . '</option>'; } 

3 Comments

Using a foreach() means that you don't have to count the array and maintain a counter variable.
Yes, but if you need to access the same index in both arrays, there is no way to avoid it, even if you use a foreach() you will still need the key which is basically the index...
Using a foreach() is the most elegant and concise way -- it automatically handles the changing of the key values, isn't limited to working with indexed arrays, and you only need to use the key to access the "other" array element because the value of the iterated array is more conveniently available by the foreach's value variable.
0

En laravel Livewire

return view('you_name_view', compact('data','data2')); @foreach ($data as $index => $data ) <li> <span>{{$data}}</span> <span>{{$data2[$index]}}</span> </li> @endforeach 

1 Comment

The question is not asking how to write a loop in a blade/template. The crux of the advice (excluding the blade syntax changes) in this answer is already presented in the accepted answer.
-1
if(isset($_POST['doors'])=== true){ $doors = $_POST['doors']; }else{$doors = 0;} if(isset($_POST['windows'])=== true){ $windows = $_POST['windows']; }else{$windows = 0;} foreach($doors as $a => $b){ 

Now you can use $a for each array....

$doors[$a] $windows[$a] .... } 

1 Comment

This unexplained answer is not terribly clear and if it has any redeeming wisdom, those insights already exist in the accepted answer.
-1

Few arrays can also be iterated like this:

foreach($array1 as $key=>$val){ // Loop though one array $val2 = $array2[$key]; // Get the values from the other arrays $val3 = $array3[$key]; $result[] = array( //Save result in third array 'id' => $val, 'quant' => $val2, 'name' => $val3, ); } 

1 Comment

Adding an extra array doesn't prevent this answer from being redundant -- the accepted answer offered this guidance many years earlier.
-1

This will only work if the both array have same count.I try in laravel, for inserting both array in mysql db

$answer = {"0":"0","1":"1","2":"0","3":"0","4":"1"};
$reason_id = {"0":"17","1":"19","2":"15","3":"19","4":"18"};

 $k= (array)json_decode($answer); $x =(array)json_decode($reason_id); $number = COUNT(json_decode($reason_id, true)); if($number > 0) { for($i=0; $i<$number; $i++) { $val = new ModelName(); $val->reason_id = $x[$i]; $val->answer =$k[$i]; $val->save(); } } 

2 Comments

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
There is nothing unique and valuable in this answer. The advice to count, check if populated, then use a for() loop was already posted earlier.
-1

To avoid referencing values by index and risking data corruption by using one array's values as keys via array_combine(), you can use array_map() to iterate two or more arrays at the same time.

Codes: (Demo)

  1. Implode an array populated with options tags without parameters in callabck signature:

    echo implode( "\n", array_map( fn() => vsprintf('<option value="%s">%s</option>', func_get_args()), $codes, $names ) ); 
  2. Implode an array populated with options by accumulating passed-in values with the spread operator:

    echo implode( "\n", array_map( fn(...$values) => vsprintf('<option value="%s">%s</option>', $values), $codes, $names ) ); 
  3. Transpose two or more arrays, then iterate and print the row data from the 2d array:

    foreach (array_map(null, $codes, $names) as $codeName) { vprintf('<option value="%s">%s</option>' . "\n", $codeName); } 

Using printf() family functions voids concatenation and interpolation. When creating strings containing quotes, this can help your code to be more readable.

1 Comment

I always appreciate a good no-comment-vengeance vote. At least I had the courage to leave a comment explaining/justifying my actions.
-2

it works for me

$counter = 0; foreach($codes as $code) { $codes_array[$counter]=$code; $counter++; } $counter = 0; foreach($names as $name) { echo $codes_array[$counter]."and".$name; $counter++; } 

1 Comment

The whole idea is that you don't need to write two separate loops.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.