【问题标题】:What's an actual use of variable variables?变量变量的实际用途是什么?
【发布时间】:2011-04-01 05:18:45
【问题描述】:

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

【问题讨论】:

    标签: php variable-variables


    【解决方案1】:

    我主要使用它来减少在 php 文件开头清理 get/post 数据时的复制粘贴: 它使用正确的名称制作经过清理的变量:

    $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= '';
    

    希望对你有帮助

    【讨论】:

    • 为什么不只是array_map
    【解决方案2】:

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

    我从不使用它们。

    【讨论】:

    • // 允许新手程序员在不使用复合类型(数组和对象)之类“复杂的东西”的情况下动态更改数据 // 学会了就不复杂了。
    • 我认为这就是引号的意思。
    • 它们完全没用。
    【解决方案3】:

    我发现它在单个场景中很有用。我有 JSON 格式的 YouTube API 结果,像这样

     $obj->media$title => Video title
    

    所以我像这样使用它

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

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

    【讨论】:

    • 你可以这样做$obj->{'media$title'}
    【解决方案4】:

    考虑在模板系统中使用 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; ?>!
    

    【讨论】:

    • extract也可以做到这一点
    • 现在你有一个错误$vars 有一个密钥"file"。这就是为什么变量变量(以及extract,就此而言)是危险的。在模板中使用$m['var'] 之类的东西会更难吗?
    • @Daniel:代码示例明确表示可以使用 extract() 来完成。这是一个例子。 @Artefecto:这不是为了证明安全性,而是使用可变变量。我从不提倡像 $_GET 数组中的任何东西一样盲目地传递变量。
    【解决方案5】:

    变量变量本质上是一个数组(地图/字典)。以下是等效的想法:

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

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

    【讨论】:

      【解决方案6】:

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

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

      所以任何时候你做一个动态的方法/函数调用,你都在使用变量变量...

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

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

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

      我从来没有直接使用过$$var 语法(我想我也不会)。我已经看到它用于通过名称 global $$name; echo $$name; 访问全局变量,但同样的事情可以用 $_GLOBALS[$name] 语法完成,所以这不是一个好的用例(更不用说使用全局变量通常被视为不好练习)...

      【讨论】:

      • 那些不是可变变量。方法不是变量。
      • 虽然他们可以(有点)如果继续下去:wiki.php.net/rfc/closures/…
      • 这是一个变量函数。你说得对。尽管如此,它仍然在相同的主体上运行(取消引用变量以确定执行路径)......
      猜你喜欢
      • 2010-09-20
      • 2016-06-03
      • 2018-05-17
      • 1970-01-01
      • 2010-12-21
      • 1970-01-01
      • 1970-01-01
      • 2020-12-17
      • 2015-09-12
      相关资源
      最近更新 更多