2012-05-18 68 views
3

我想在運行時配置對象傳遞一個回調函數,像這樣:在對象上下文中運行的回調函數?

class myObject{ 
    protected $property; 
    protected $anotherProperty; 

    public function configure($callback){ 
    if(is_callable($callback)){ 
     $callback(); 
    } 
    } 
} 

$myObject = new myObject(); // 
$myObject->configure(function(){ 
    $this->property = 'value'; 
    $this->anotherProperty = 'anotherValue'; 
}); 

當然,我得到以下錯誤:

Fatal error: Using $this when not in object context

我的問題是,如果有一種方法來在回調函數中使用$this來實現此行爲,或者可以獲得更好模式的建議。

PS:我更喜歡使用回調。

回答

6

你的想法開始,你可以通過$this作爲參數傳遞給你的回調

但需要注意的是回調(這不是你的類中聲明)將無法​​訪問受保護的,也不私人財產/方法 - 這意味着你將不得不建立公共方法來訪問這些。


你的類,那麼應該是這樣的:

class myObject { 
    protected $property; 
    protected $anotherProperty; 
    public function configure($callback){ 
    if(is_callable($callback)){ 
     // Pass $this as a parameter to the callback 
     $callback($this); 
    } 
    } 
    public function setProperty($a) { 
    $this->property = $a; 
    } 
    public function setAnotherProperty($a) { 
    $this->anotherProperty = $a; 
    } 
} 

而且你宣佈你的回調,並使用它,就像這樣:

$myObject = new myObject(); // 
$myObject->configure(function($obj) { 
    // You cannot access protected/private properties or methods 
    // => You have to use setters/getters 
    $obj->setProperty('value'); 
    $obj->setAnotherProperty('anotherValue'); 
}); 


調用下面的一行後面的代碼:

var_dump($myObject); 

將輸出這樣的:

object(myObject)[1] 
    protected 'property' => string 'value' (length=5) 
    protected 'anotherProperty' => string 'anotherValue' (length=12) 

這表明回調已經被執行,你的對象的屬性確實已設定,符合市場預期。

+1

+1這是向前邁進了一大步。在接受之前,我會等待一段可能的更好的答案。 – marcio

6

如果您正在使用(或願意升級到)PHP 5.4,您可以使用新的bindTo方法Closures。這允許您將封閉「重新綁定」到新的範圍。

在致電$callback之前,您可以將其$this設置爲您想要的值。

if(is_callable($callback)){ 
    $callback = $callback->bindTo($this, $this); 
    $callback(); 
} 

DEMO:http://codepad.viper-7.com/lRWHTn

您還可以使用bindTo外的類。

$func = function(){ 
    $this->property = 'value'; 
    $this->anotherProperty = 'anotherValue'; 
}; 
$myObject->configure($func->bindTo($myObject, $myObject)); 

DEMO:http://codepad.viper-7.com/mNgMDz

+3

+1這是將PHP升級到最新版本的另一個原因;-) –

+1

+1這是一個很好的答案,但不幸的是我必須保持代碼與PHP5.3兼容*(全部添加5.3標籤) – marcio

+0

@ marcioAlmada:無論如何我會在這裏留下。 :-P –

相關問題