Search code examples
phpfunctionvariable-variables

Using variable variables in simple PHP function


The other day I was given this huge set of arrays and told to make a HTML page with a bunch or selects/radio buttons so I wrote some simple functions to simplify things.

This is my function to generate very large HTML selects.

function genSelect($name) {
    $selectReturn = '<select name="'.$name.'">';
        foreach(${$name} as $value=>$text){
            $selectReturn .= '<option value="'.$value.'"';
            if($evalThis->loaded_settings[$name]['value']==$value)
                $selectReturn .= ' SELECTED ';
            $selectReturn .= '>'.$text.'</option>';
        }
    $selectReturn .= '</select>';
return $selectReturn;
}

This doesn't seem to work because ${$name} simply does not call anything / work like I expect it too. I already have a work around where I just pass the array though the function call but its been bugging me what I was doing wrong with the variable variables in this code.

Edit: To give some context this is being loaded in a joomla view to build the giant UI for entering in settings. This function is in a lib file and is loaded with a require_once along side another file containing all the arrays I use. The database holds only the current values of these settings and the arrays contain all the possible options for the various selects/radio/dropdown menus and are centralized in a separate file for language/translation reasons.

Clarifying some questions people asked, $name simply contains the name of the array used and also the name of the HTML select/radio/checkbox input. $evalThis is a array containing the values the database currently has.


Solution

  • it seems an array with name stored in $name is defined in global context, not in this function.

    $somearr = array('x', 'y');
    function genSelect($name) {
        $selectReturn = '<select name="'.$name.'">';
    
        foreach(${$name} as $value=>$text){
            $selectReturn .= '<option value="'.$value.'"';
            if($evalThis->loaded_settings[$name]['value']==$value)
                $selectReturn .= ' SELECTED ';
            $selectReturn .= '>'.$text.'</option>';
        }
    
        $selectReturn .= '</select>';
        return $selectReturn;
    }
    echo genSelect('somearr'); //doesnt work, somearr is global
    
    
    $somearr = array('x', 'y');
    function genSelect($name) {
        global $somearr;
        $selectReturn = '<select name="'.$name.'">';
    
        foreach(${$name} as $value=>$text){
            $selectReturn .= '<option value="'.$value.'"';
            if($evalThis->loaded_settings[$name]['value']==$value)
                $selectReturn .= ' SELECTED ';
            $selectReturn .= '>'.$text.'</option>';
        }
    
        $selectReturn .= '</select>';
        return $selectReturn;
    }
    echo genSelect('somearr'); //works, note 'global $somearr' line at the beginning of genSelect
    

    Generally it is quite bad design to use variable names of functions/arrays when it is not necessary/at least justified. If I were you I would just rewrite the method to

    function genSelect($array, $name) { ... }
    
    echo genSelect($someArr, 'someArr');
    

    It may seem like duplication of typying, but it's better to not have your methods depend on global scope. Btw, your $evalThis var is also out of function scope.