2010-10-31 68 views
2

最近我一直在問這個話題的幾個問題,所以我覺得把相關的問題連接起來是合適的。PHP對象和閉包

PHP closures and implicit global variable scope

我有一組使用閉包在下面的例子中類(記住我趕緊打了個一起本例中爲這個線程)我的問題包括使$obj參數的功能。

是否存在任何形式的魔法變量(cough- $this -cough),這將允許我來訪問,而不是需要申報的$obj或任何一個佔位符的說法它是從調用的對象,?也許我誤解了,但看起來我正在尋找的功能已被刪除,至少在$this的背景下。

class Test{ 

    private $_color; 
    protected $_children = array(); 

    public function __construct(Closure $function){ 
     $function($this); 
    } 

    public function create(Closure $function){ 
     return new self($function); 
    } 

    public function color($color){ 
     $this->_color = $color; 
     return $this; 
    } 

    public function add(Closure $function){ 
     $this->_children[] = new Test($function); 
     return $this; 
    } 

} 

Test::create(function($obj){ 
    $obj->color('Red') 
     ->add(function(){ 
      $obj->color('Green'); 
     }) 
     ->color('Blue'); 
    }); 

我能看到離手,唯一的選擇是在創建過程存儲每個對象的實例,並提供功能如下返回該實例:

class Test{ 

    private $_color; 
    private static $_instance; 
    protected $_children = array(); 

    public function __construct(Closure $function){ 
     self::$_instance = $this; 
     $function(); 
    } 

    . 
    . 
    . 

    public static function this(){ 
     return self::$_instance; 
    } 

} 

Test::create(function(){ 
    Test::this() 
     ->color('Red') 
     ->add(function(){ 
      Test::this() 
       ->color('Green'); 
     }) 
     ->color('Blue'); 
    }); 

回答

1

您應該使用的第一個版本。靜態提供類實例並不是很好(除了單例使用)。想象你有兩個實例。那麼只有後者將被靜態地服務。第一個你什麼都做不了。

即使採用您的第一種方法,也存在一個不重要的限制:您只能訪問公共方法。圍繞這一點使用反射有一個hacky的解決方法。那麼,你只使用公共方法嗎?

在某一點上,Closure被視爲實施細節,不被依賴。這已不再是這種情況; Closure是記錄類型的匿名函數。

+0

謝謝** nikic **;只有公共方法正在被調用,所以能見度不是問題。我意識到Closure類的不可靠性,並且在時間到時會回覆到更永久的狀態,我就像它在我使用的IDE中提供的類型提示。 無論如何,沒有任何* magic *變量或其他技巧可以用來實現這種功能? – Dan 2010-10-31 07:41:11

+1

不,沒有;) – NikiC 2010-10-31 07:44:52

+0

再次感謝** nikic ** :) – Dan 2010-10-31 07:51:39