$ this关键字和紧凑功能

Bud*_*ddy 14 php oop

为什么compact(array($this, 'variable')不起作用?我没有发现任何相关信息.

UPDATE

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

$result = $this->result;
compact('result');
Run Code Online (Sandbox Code Playgroud)

但这很难看.

Sto*_*ney 13

我知道这是旧的,但我想要一个像我这样的项目.以为我会分享我想出的解决方案:

extract(get_object_vars($this));
return compact('result');
Run Code Online (Sandbox Code Playgroud)

它很好地扩展.例如:

<?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());
Run Code Online (Sandbox Code Playgroud)

小心使用.


irc*_*ell 11

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

return array('variable' => $this->variable);
Run Code Online (Sandbox Code Playgroud)

  • "在大多数情况下,这是毫无意义的" - 你能详细说明吗? (3认同)
  • 我也没有得到你的笔记.紧凑帮助了我很多次 (2认同)

Gor*_*don 7

compact()当前符号表中查找变量名称.$this在那里不存在.无论如何,你期望这个名字$this是什么?

你可以做:

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

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


更新后编辑

compact($this->result);查找在方法的本地/当前范围内定义的"某事" output().由于没有这样的变量,结果数组将为空.这可行:

public function output() 
{
    $something = 1;
    print_r( compact($this->result) );
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*ger 6

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

当然,这为您提供了该类的所有属性(无论访问控制修饰符如何),因此您很可能还想过滤此列表。执行此操作的一种简单(如果有些混乱)的方法是按照此 SE Answerarray_intersect_key()一起使用。所以整个事情看起来像:array_flip()

array_intersect_key( get_class_vars( get_called_class() ), array_flip( array( 'var_1', 'var_2', 'var_3' ) ) );
Run Code Online (Sandbox Code Playgroud)

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

然而,因为a)我喜欢Yak Shaving,b)因为我是一个非常勤奋的懒程序员,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() );
Run Code Online (Sandbox Code Playgroud)

这会产生预期的输出:

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" }
Run Code Online (Sandbox Code Playgroud)

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