Repository: codeigniter4/CodeIgniter4 (PHP)

Issue:
Bug: selected value in multidimensional form_dropdown
**Bug**
the selected value does not work in form_dropdown helper with a multidimensional array as input

**Solution to fix it**
In this file : /system/Helpers/form_helper.php 
between line 320 and 321 add the following code : 
`$optgroupKey = (string) $optgroupKey;`

(Exactly as in line 311, so as not to compare an integer with a string)





Discussion:
If you have a solution, please submit a Pull Request!



Patch:
diff --git a/system/Helpers/form_helper.php b/system/Helpers/form_helper.php
index bb4f6cd8060f..e33ec2e89137 100644
--- a/system/Helpers/form_helper.php
+++ b/system/Helpers/form_helper.php
@@ -298,7 +298,7 @@ function form_dropdown($data = '', $options = [], $selected = [], $extra = ''):
             }
         }
 
-        // standardize selected as strings, like  the option keys will be.
+        // Standardize selected as strings, like the option keys will be
         foreach ($selected as $key => $item) {
             $selected[$key] = (string) $item;
         }
@@ -308,6 +308,7 @@ function form_dropdown($data = '', $options = [], $selected = [], $extra = ''):
         $form     = '<select ' . rtrim(parse_form_attributes($data, $defaults)) . $extra . $multiple . ">\n";
 
         foreach ($options as $key => $val) {
+            // Keys should always be strings for strict comparison
             $key = (string) $key;
 
             if (is_array($val)) {
@@ -318,6 +319,9 @@ function form_dropdown($data = '', $options = [], $selected = [], $extra = ''):
                 $form .= '<optgroup label="' . $key . "\">\n";
 
                 foreach ($val as $optgroupKey => $optgroupVal) {
+                    // Keys should always be strings for strict comparison
+                    $optgroupKey = (string) $optgroupKey;
+
                     $sel = in_array($optgroupKey, $selected, true) ? ' selected="selected"' : '';
                     $form .= '<option value="' . htmlspecialchars($optgroupKey) . '"' . $sel . '>' . $optgroupVal . "</option>\n";
                 }


Test patch:
diff --git a/tests/system/Helpers/FormHelperTest.php b/tests/system/Helpers/FormHelperTest.php
index e7a669847ed9..4a1ef8fcddcd 100644
--- a/tests/system/Helpers/FormHelperTest.php
+++ b/tests/system/Helpers/FormHelperTest.php
@@ -435,6 +435,34 @@ public function testFormDropdownUnselected()
         $this->assertSame($expected, form_dropdown('cars', $options));
     }
 
+    public function testFormDropdownKeyCasting()
+    {
+        $options = [
+            'Swedish Cars' => [
+                '1' => 'Volvo',
+                '2' => 'Saab',
+            ],
+            2 => [
+                3   => 'Mercedes',
+                '4' => 'Audi',
+            ],
+        ];
+        $selected = [2];
+        $expected = <<<EOH
+            <select name="cars">
+            <optgroup label="Swedish Cars">
+            <option value="1">Volvo</option>
+            <option value="2" selected="selected">Saab</option>
+            </optgroup>
+            <optgroup label="2">
+            <option value="3">Mercedes</option>
+            <option value="4">Audi</option>
+            </optgroup>
+            </select>\n
+            EOH;
+        $this->assertSame($expected, form_dropdown('cars', $options, $selected));
+    }
+
     public function testFormDropdownInferred()
     {
         $options = [