在简单的PHP函数中使用变量

Using variable variables in simple PHP function

提问人:Spunkie 提问时间:1/4/2012 最后编辑:Spunkie 更新时间:1/4/2012 访问量:151

问:

前几天,我得到了这组巨大的数组,并被告知要用一堆或选择/单选按钮制作一个 HTML 页面,所以我编写了一些简单的函数来简化事情。

这是我生成非常大的 HTML 选择的功能。

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;
}

这似乎不起作用,因为根本没有像我所期望的那样调用任何东西/工作。我已经有了一个解决方法,我只是通过函数调用传递数组,但它一直困扰着我,我在这个代码中的变量变量上做错了什么。${$name}

编辑:为了提供一些上下文,它被加载到joomla视图中,以构建用于输入设置的巨型UI。这个函数在一个 lib 文件中,并与另一个包含我使用的所有数组的文件一起加载。数据库仅保存这些设置的当前值,数组包含各种选择/单选/下拉菜单的所有可能选项,并且出于语言/翻译原因集中在一个单独的文件中。require_once

澄清人们提出的一些问题,只需包含所用数组的名称以及 HTML select/radio/checkbox 输入的名称。 是包含数据库当前具有的值的数组。$name$evalThis

PHP 函数 变量

评论

0赞 FlipMcF 1/4/2012
您能举例说明$name中的数据是什么样子的吗?
1赞 PeeHaa 1/4/2012
我只想问:做什么?听起来有点.$evalThisevil
0赞 The Nail 1/4/2012
试试这个:$evalThis = new stdClass(); $evalThis->loaded_settings = array('abc' => array('value' => 1));

答:

1赞 Mariusz Sakowski 1/4/2012 #1

似乎一个名称存储在 $name 中的数组是在全局上下文中定义的,而不是在这个函数中定义的。

$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

一般来说,在没有必要/至少没有理由的情况下使用函数/数组的变量名称是相当糟糕的设计。如果我是你,我会将方法重写为

function genSelect($array, $name) { ... }

echo genSelect($someArr, 'someArr');

这似乎是重复打字,但最好不要让你的方法依赖于全局范围。 顺便说一句,你的 $evalThis var 也超出了函数范围。

评论

2赞 noob 1/4/2012
使用 PHP DOM 使用 PHP 创建 HTML!
0赞 Spunkie 1/4/2012
请原谅我,如果这是一个愚蠢的问题,我仍然是PHP的新手。如果加载包含所有数组的文件从其当前位置移动到函数内部,直接在加载包含此函数的文件的正上方,这是否意味着会起作用?${$name}require_oncerequire_once
0赞 The Nail 1/4/2012
我不确定您指的是哪个代码,但是如果您从函数中执行操作,那么在包含的文件中具有“全局”范围的任何内容都将在函数范围内。但不建议从函数中包含;而是包含函数并在需要时调用它们。另请注意,如果之前已经包含相同的文件,则 (或 ) 不会执行任何操作,即使在不同的范围内也是如此。require_oncerequire_onceinclude_once
1赞 FtDRbwLXw6 1/4/2012 #2

问题在于没有在函数的范围内定义。您需要像这样引用全局变量:${$name}

$GLOBALS[$name]  // bad

或者在函数顶部添加以下内容:

global ${$name};  // worse

警告:这太可怕了。不要这样做:-)我建议像您之前提到的那样简单地传递数组。

评论

0赞 PeeHaa 1/4/2012
第一个答案是谁做对了(至少是关于全球部分)。不过还没有验证你的答案:)
2赞 Bart 1/4/2012
如果选择使用全局变量(希望不是),您也可以直接使用,而不是首先定义全局变量。$GLOBALS[$name]${$name}
0赞 FtDRbwLXw6 1/4/2012
@Bart:你说得很对。我将修改我的答案以反映这一点。谢谢。