$ this关键字和紧凑功能

时间:2011-02-14 16:42:26

标签: php oop

为什么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');

但这很难看。

7 个答案:

答案 0 :(得分:11)

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

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

答案 1 :(得分:10)

我知道这已经过时了,但我想为我正在进行的项目想要这样的东西。以为我分享了我想出的解决方案:

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());

小心使用。

答案 2 :(得分:6)

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

你可以这样做:

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

具有讽刺意味的是,一旦你将$ 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) );
}

答案 3 :(得分:4)

您希望使用get_class_vars(),它返回所提供类的所有属性(类变量)的关联数组,并将var名称作为键。在课堂上使用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' ) ) );

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

然而,因为a)我喜欢Yak Shaving和b)因为我是一个非常勤奋的lazy programmer和c)在Perl中可能有一个优雅的单线程,在这里&#39;在我试图解决的问题的上下文中的代码:用相同类的数量(但不是全部)其他属性覆盖关联数组(这也是当前类的属性)。 / p>

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

请注意,在我自己的用法中,我不会将其分为2行,但我希望将引用OP的代码分开。

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

我今天需要这样的东西– $(document).ready(function () { $("#testG").click(function () { alert("1"); //your code }); }); 的功能,但是在对象的范围内,而不是在当前符号表的范围内。所以我写了这个:

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" } 一样,如果包含无效的属性名称作为参数,它将发出通知。

答案 6 :(得分:0)

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

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

这样你就可以继续为你的其他漂亮变量使用 compact!