2011-02-14 308 views
8

爲什麼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 
    } 
} 

我在此刻只有一種解決方案:

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

但是,這是醜陋的。

+0

我對這個函數或「提取」不是很瞭解,但是我可以告訴你在那裏末尾沒有括號。可能只是一個轉位問題,但也許這是你的問題? 在其他消息中,我會冒險猜測$這不是對象符號表的一部分,因此不能正確打包。 – rockerest 2011-02-14 16:49:08

+0

不需要`array()`,你必須指定'this',而不是$ this。 – greg0ire 2011-02-14 16:53:20

+0

@ greg0rie,這是你的作品嗎?你使用哪個PHP版本? – Buddy 2011-02-17 17:07:07

回答

8

簡短的回答:不要使用compact()。在這種情況下,這是毫無意義的(在大多數情況下,這毫無意義,但這是另一回事)。相反,剛剛返回一個數組有什麼問題?

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

compact()查找在current symbol table變量名。那裏不存在$this。你認爲$this的名字是什麼?

你可以這樣做:

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

諷刺的是,一旦你分配$這$是,$這也可以用的「那個」「這個」 nistead壓實。見http://bugs.php.net/bug.php?id=52110。出於性能原因$this和超級全局只在需要時填充。如果不需要,他們不存在。


編輯更新

compact($this->result);後會查找output()方法本地/電流範圍內定義的 '東西'。由於沒有這樣的變量,所以得到的數組將是空的。這將工作:

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

您需要使用get_class_vars(),它返回所提供的類的所有屬性(類瓦爾)的關聯數組,使用var名稱作爲關鍵。使用類內部的get_class_vars(get_called_class())將該類的名稱作爲字符串獲取。 get_class($this)也適用。

當然,這會給你全部該類的屬性(不管訪問控制修飾符),所以你也可以過濾這個列表。一個簡單的(如果有點混淆)的方式是使用array_intersect_key()以及array_flip()根據this SE Answer。所以整個事情看起來像:

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中可能有一行代碼優雅地做了這個,這裏是代碼在我遇到的問題的上下文中試圖解決:用相同類的數量(但不是全部)其他屬性重寫一個關聯數組(也是當前類的一個屬性)。

<?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分開。

7

我知道這是舊的,但我想爲我正在進行的項目這樣的事情。以爲我會分享我想出的解決方案:

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

請謹慎使用。