【问题标题】:$this keyword and compact function$this 关键字和紧凑函数
【发布时间】:2011-06-27 01:17:14
【问题描述】:

在某些情况下,我们可以使用array($this, 'variable') 语法来引用对象属性。为什么compact(array($this, 'variable')) 不起作用?有没有办法解决这个问题?


class someclass {

    $result = 'something';

    public function output() {
        compact($this->result); // $this is a OOP keyword and I don't know how to use it inside a compact() brackets
    }
}

目前我只找到了一种解决方案:

$result = $this->result;
compact('result');

但这很丑。

【问题讨论】:

  • 我对这个函数或“提取”知之甚少,但我可以告诉你,你在最后缺少一个括号。可能只是一个换位问题,但也许这是你的问题?在其他新闻中,我冒昧地猜测 $this 不是对象符号表的一部分,因此无法正确打包。
  • 不需要array(),你必须指定'this',而不是$this。
  • @greg0rie,这对你有用吗?您使用哪个 PHP 版本?

标签: php arrays oop


【解决方案1】:

我正在寻找同样的东西,想要防止 丑陋。后来我最终使用了以下代码,认为我应该在这里贡献它:

return array_merge(compact('other', 'beautiful', 'variables'), 
  ['result' => $this->result]);

这样您就可以继续使用 compact 来处理其他漂亮的变量!

【讨论】:

    【解决方案2】:

    我今天需要这样的东西——compact 的功能,但在对象范围内而不是在当前符号表中。所以我写了这个:

    if (!function_exists("compact_with")) {
        /**
         * Create an array of selected object properties and their values
         *
         * @param mixed $obj The object from which to take properties
         * @param mixed $args The property names as strings or arrays of strings
         * @return array An associative array of properties and their values
         */
        function compact_with($obj, ...$args): array
        {
            array_map(
                function($v) use($obj, &$ret) {
                    $ret[$v] = is_array($v) ? compact_with($obj, ...$v) : $obj->$v;
                },
                $args
            );
            return $ret ?? [];
        }
    }
    
    $foo->foo = "foo";
    $foo->bar = "bar";
    $foo->baz = "baz";
    $result = compact_with($foo, "bar", "foo", "baz");
    var_dump($result);
    

    输出:

    array(3) {
      'bar' =>
      string(3) "bar"
      'foo' =>
      string(3) "foo"
      'baz' =>
      string(3) "baz"
    }
    

    compact 一样,如果包含无效属性名称作为参数,它会发出通知。

    【讨论】:

      【解决方案3】:

      我知道这是旧的,但我想要这样的东西用于我正在进行的项目。想我会分享我想出的解决方案:

      extract(get_object_vars($this));
      return compact('result');
      

      它可以很好地扩展。例如:

      <?php
      
      class Thing {
          private $x, $y, $z;
      
          public function __construct($x, $y, $z) {
              $this->x = $x;
              $this->y = $y;
              $this->z = $z;
          }
      
          public function getXYZ() {
              extract(get_object_vars($this));
              return compact('x', 'y', 'z');
          }
      }
      
      
      $thing = new Thing(1, 2, 3);
      print_r($thing->getXYZ());
      

      小心使用。

      【讨论】:

      • 感谢您回答问题。
      • $vars = get_object_vars($this); extract($vars); return compact(array_keys($vars)); 获取对象的所有属性
      【解决方案4】:

      您需要使用get_class_vars(),它返回一个包含所提供类的所有属性(类变量)的关联数组,变量名作为键。使用类中的get_class_vars( get_called_class() ) 以字符串形式获取该类的名称。 get_class( $this ) 也可以。

      当然,这会为您提供所有类的属性(无论访问控制修饰符如何),因此您可能还想过滤此列表。一个简单(如果有点混淆)的方法是按照this SE Answer 使用array_intersect_key()array_flip()。所以整个事情看起来像:

      array_intersect_key( get_class_vars( get_called_class() ), array_flip( array( 'var_1', 'var_2', 'var_3' ) ) );
      

      您必须决定生成的代码是否真的值得。正如@ircmaxell 指出的那样,阅读array( 'var_1' =&gt; $this-&gt;var_1, 'var_2' =&gt; $this-&gt;var_2 ); 可能更容易。

      但是,因为 a) 我喜欢 Yak Shaving 和 b) 因为我是一个非常勤奋的 lazy programmer 和 c) Perl 中可能有一个单行代码可以优雅地做到这一点,这里是上下文中的代码我试图解决的问题:用同一类的许多(但不是全部)其他属性覆盖关联数组(这也是当前类的属性)。

      <?php
      class Test {
          protected $var_1 = 'foo';
          private $var_2 = 'bar';
          public $var_3 = 'baz';
          private $ignored_var = 'meh';
      
          public $ary = array( 
              'var_1' => 'bletch',
              'var_2' => 'belch',
              'var_4' => 'gumbo',
              'var_5' => 'thumbo'
          );
      
          public function test(){
              $override = array_intersect_key( get_class_vars( get_called_class() ), array_flip( array( 'var_1', 'var_2', 'var_3' ) ) );
              return array_merge( $this->ary, $override );
          }
      }
      
      $test = new Test();
      var_dump( $test->test() );
      

      产生预期的输出:

      array(5) { ["var_1"]=> string(3) "foo" ["var_2"]=> string(3) "bar" ["var_4"]=> string(5) "gumbo" ["var_5"]=> string(6) "thumbo" ["var_3"]=> string(3) "baz" }
      

      请注意,在我自己的用法中,我不会将其分成两行,但我想将引用 OP 的代码分开。

      【讨论】:

      • 咕噜咕噜 - the sound a yak makes
      • 作为一个幽默的轶事,在给这只牦牛剃毛并写了这个可爱的 SE 答案后,事实证明它根本不适合我:我的类属性与预期的名称不同我的关联数组中的参数。看起来我将使用 'var_1' => $this->some_other_var。卫生部
      【解决方案5】:

      compact()current symbol table 中查找变量名。 $this 在那里不存在。你希望$this 的名字是什么?

      你可以这样做:

      class Foo
      {
          function __construct()
          {
              $that = $this;
              $var = '2';
              print_r( compact(array('that', 'var')) );
          }
      }
      

      具有讽刺意味的是,一旦您将 $this 分配给 $that,$this 也可以使用 'this' 而不是 'that' 进行压缩。见http://bugs.php.net/bug.php?id=52110。出于性能原因$this 和超级全局变量仅在需要时才被填充。如果不需要,它们就不存在。


      更新后编辑

      您的compact($this-&gt;result); 查找在output() 方法的local/current 范围内定义的“某物”。由于没有这样的变量,因此结果数组将为空。这会起作用:

      public function output() 
      {
          $something = 1;
          print_r( compact($this->result) );
      }
      

      【讨论】:

        【解决方案6】:

        简答:不要使用compact()。在这种情况下,它是没有意义的(在大多数情况下它是没有意义的,但那是另一回事了)。相反,只返回一个数组有什么问题?

        return array('variable' => $this->variable);
        

        【讨论】:

        • “在大多数情况下它是没有意义的” - 请您详细说明一下吗?
        • 我也没有收到你的笔记。紧凑帮了我很多次
        • 虽然我同意这种情况,正如@chris 所问的那样,你能解释一下为什么这个函数没有意义,所以其他人可以理解吗?
        • 我想他只是想说你不需要一个函数来做 array('key' => $val).. 哈哈
        • 我个人不喜欢使用紧凑型。乍一看,当我使用尚未定义的变量名时,PHPStorm 并没有突出显示问题。重构变量名也有点困难(必须使用重命名所有出现,我不喜欢这样做)
        【解决方案7】:

        您必须定义索引字段。就像是: $array = compact('this', '变量')

        http://php.net/manual/en/function.compact.php

        【讨论】:

          猜你喜欢
          • 2012-07-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-17
          • 1970-01-01
          • 1970-01-01
          • 2017-10-25
          • 1970-01-01
          相关资源
          最近更新 更多