Question

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.

Was it helpful?

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.

OTHER TIPS

The problem is that ${$name} is not defined inside the function's scope. You would need to either reference the global variable like this:

$GLOBALS[$name]  // bad

Or add this at the top of the function:

global ${$name};  // worse

WARNING: This is horrible. Don't do it :-) I advise simply passing the array like you mentioned before.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top