变量的实际用途是什么?

What's an actual use of variable variables?

提问人:user151841 提问时间:8/19/2010 最后编辑:Peter Mortensenuser151841 更新时间:3/19/2023 访问量:1860

问:

变量看起来很酷,但我想不出在生产环境中实际使用它们的场景。这样的场景会是什么?它们是如何使用的?

php 变量

评论


答:

7赞 Artefacto 8/20/2010 #1

我猜,它的目的是允许新手程序员动态更改数据,而无需使用复合类型(数组和对象)等“复杂的东西”。

我从不使用它们。

评论

0赞 dreftymac 11/27/2012
允许新手程序员在不使用复合类型(数组和对象)等“复杂的东西”的情况下动态更改数据 // 一旦学习,它就不复杂了。
1赞 user151841 11/27/2012
我认为这就是引号的意思。
3赞 frosty 10/15/2015
他们完全没用。
0赞 mickmackusa 6/27/2022
由于 Stack Overflow 上有这么多页面被路由到这里,我希望这个公认的答案更加严厉。我发现变量比数组/对象更复杂。而且,IDE 可能会丢失对动态命名变量的跟踪并发出错误警告。
0赞 Jage 8/20/2010 #2

可以考虑在模板系统中使用它,在模板系统中,您正在使用 PHP 文件并需要设置变量:

function fetch_template($file, $vars){
    $ret = 'File not loaded.';
    if(file_exists(TEMPLATE_PATH.$file)){
        //could do this with extract() but I am showing you
        foreach($vars as $varName => $value){
            ${$varName} = $value;
        }
        ob_start();
        include(TEMPLATE_PATH.$file);
        $ret = ob_get_contents();
        ob_end_clean();
    }
    return $ret;
}

现在,假设您在模板中使用了这些变量名称,您可以调用它并将变量传递到其中以供使用。

echo fetch_template('hi_there.tpl', array('name'=>'JJ'));

然后在您的模板中:

Hello <?php echo $name; ?>!

评论

0赞 Daniel Vandersluis 8/20/2010
同样的事情也可以用提取来完成
2赞 Artefacto 8/20/2010
现在你有一个错误有一个密钥.这就是为什么变量(和,就此而言)是危险的。在模板中使用类似的东西会更难吗?$vars"file"extract$m['var']
0赞 Jage 8/20/2010
@Daniel:代码示例明确表示可以使用 extract() 完成。这是一个例子。@Artefecto:这不是为了证明安全性,而是使用变量。我从不主张像 $_GET 数组中的任何内容一样盲目地传入变量。
0赞 ircmaxell 8/20/2010 #3

就我个人而言,我经常使用它们。以下类型的所有调用都使用变量变量:

$foo->$bar = 'test';
$foo->$bar();
$bar();

因此,每当您进行动态方法/函数调用时,您都在使用变量变量......

这样做的常见用途是通过魔术方法访问受保护的属性。我经常看到以下内容:__get

public function __get($name) {
    return isset($this->$name) ? $this->$name : null;
}

根据定义,它是使用变量变量来提供对受保护成员的读取访问权限......

我从未直接使用过该语法(并且认为我永远不会)。我已经看到它用于按名称访问全局变量,但是语法也可以做同样的事情,所以这不是一个好的用例(更不用说使用全局变量通常被视为不好的做法)......$$varglobal $$name; echo $$name;$_GLOBALS[$name]

评论

1赞 Artefacto 8/20/2010
这些不是变量。方法不是变量。
0赞 Artefacto 8/20/2010
尽管如果这种情况继续下去,它们可以(有点):wiki.php.net/rfc/closures/......
0赞 ircmaxell 8/20/2010
它是一个变量函数。你是对的。不过,它仍然在相同的主体上运行(其中变量被取消引用以确定执行路径)......
1赞 Arshdeep 8/20/2010 #4

我发现它在单个场景中很有用。我有 JSON 格式的 YouTube API 结果,如下所示

 $obj->media$title => Video title

所以我用它

$mt = 'media$title';
$obj->$mt ;

所以它在这里对我有用:)

评论

0赞 Artefacto 8/20/2010
你可以做.$obj->{'media$title'}
2赞 Matthew 8/20/2010 #5

变量变量本质上是一个数组(map/dictionary)。以下是等效的想法:

<?php
$foo = array('a' => 1);
$bar = 'a';
echo $foo[$bar]."\n";

$foo_a = 1;
$bar = 'a';
$vv = "foo_$bar";
echo $$vv."\n";
?>

因此,如果你把你的“变量变量”包装成一个父数组,你可以去掉它们。

我见过人们在类中使用变量属性:

<?php
class Foo
{
  private $a = 1;

  public function __get($key)
  {
    if (isset($this->$key)) return $this->$key;
  }
}

$foo = new Foo();
echo $foo->a;
?>

但同样,您可以使用数组:

<?php
class Foo
{
  private $props = array('a' => 1);

  public function __get($key)
  {
    if (array_key_exists($key, $this->props))
      return $this->props[$key];
  }
}

$foo = new Foo();
echo $foo->a;
?>

课外:

<?php
class Foo
{
  public $a = 1;
}

$foo = new Foo();
$prop = 'a';
echo $foo->{$prop};
?>

因此,在编写自己的受控代码时,您永远不必“必须”使用变量或变量属性。我个人的偏好是永远不要使用变量。我偶尔会使用变量属性,但当我以这种方式访问数据时,我更喜欢使用数组。

0赞 Omidoo 8/12/2017 #6

我主要用它来减少在 php 文件开头清理获取/发布数据时的复制粘贴: 它使用专有名称创建经过清理的变量:

$fields=array('age','name','gender','email','username');

foreach($fields as $field) {
    if (empty($_REQUEST[$field] === false)
        ${$field} = sanitize($_REQUEST[$field]);
    else
        ${$field} = '';
}

而不是所有这些行:

if (empty($_GET['age']) === false) 
    $age= sanitize($_GET['age']);
else
    $age= '';

if (empty($_GET['name']) === false) 
    $name= sanitize($_GET['name']);
else
    $name = '';

if (empty($_GET['gender']) === false) 
    $gender= sanitize($_GET['gender']);
else
    $gender= '';

if (empty($_GET['email']) === false) 
    $email= sanitize($_GET['email']);
else
    $email= '';

if (empty($_GET['username']) === false) 
    $username= sanitize($_GET['username']);
else
    $username= '';

我希望它有所帮助

评论

0赞 user151841 8/12/2017
为什么不只是 ?array_map
0赞 mickmackusa 6/27/2022
我根本不会创建单个变量。我会将这些键(、等)推入我的数组。agename$sanitized
0赞 Sebas Rossi 3/19/2023 #7

我知道这是一个旧线程,变量不是很常用。事实上,如果它在未来的版本中被弃用,我不会感到惊讶。

但我发现它作为 switch 语句的替代品非常有用,更干净、简单和简短的解决方案。此外,它似乎比 switch 语句更有效地执行。

所以这个:

class AlterSwitch{

    public static function the_case($option){

        $dirname = dirmane(__DIR__);

        switch ($option){
            case 'root':
                $section = $dirname . '/templates/root.html';
                break;
            case 'head':
                $section = $dirname . '/templates/head.html';
                break;        
            case 'item_cont':
                $section = $dirname . '/templates/item_cont.html';
                break;
            case 'item':
                $section = $dirname . '/templates/item.html';
                break;
    }
    return $section;

}

可以变成这样:

class AlterSwitch{

    public static function the_case($option){

        $dirname = dirmane(__DIR__);

        $root = $dirname . '/templates/root.html';
        $head = $dirname . '/templates/head.html';
        $item_cont = $dirname . '/templates/item_cont.html';
        $item = $dirname . '/templates/item.html';

        if($$option!==null){
            # Variable variable is the parameter and returns the Variable of this class
            return $$option;
    } 
    return "File not found";  
    }

}


// Instantiate e.g.
// For both classes
// returns $section - $head

AlterSwitch::the_case('head'));