2010-11-04 96 views
1

這裏的前提是:動態函數參數和使用__call

我有很多課,我需要之前,從任何一個類被稱爲任何方法執行一個動作,我的解決辦法是讓所有的類擴展這將定義哪些看起來像一個()函數調用父類:

public function call($method){ 
    //do the something I need to do before method calls 
    $params = func_get_args(); 
    //remove the $method param from the $params array 
    unset($params[0]); 
    return $this->__call($method,$params); 
} 

然後只需撥打呼叫方法,並指定我想叫實際的方法,這樣的方法將被調用,但裏面的調用方法(該類從我的父類繼承)我可以執行我需要在指定的方法獲得之前執行的操作調用。

這需要能夠支持論點,可能是數組或字符串,所以任何涉及爆參數數組是不行的(因爲這會承擔所有的參數都是字符串)。

我不知道如果我有什麼上面是有道理的,我想檢查,看看如果我要對這個錯誤的方式或不。

任何想法/想法將不勝感激。

謝謝! PS:我應該注意,我對上述情況的描述聽起來像子類擴展父類的原因僅僅是爲了這個目的,實際上還有更多的原因(我的父類擴展了Zend_Db_Table_Abstract和我的數據庫模型擴展父項)。

回答

2

__call被自動調用,如果它的定義。這就是爲什麼這是一個「魔術」的方法。直接使用它似乎很奇怪,而不是在它打算的上下文中使用它。在這裏,你可能已經命名了任何東西。

可能絕對使用__call的力量在這裏你的優勢。嘗試在它們之前用下劃線命名所有成員函數。所以,如果你之前有$this->print()你現在有$this->_print()。然後,在您的__call函數中,添加下劃線並使用call_user_func_array(array($this,"_$name"), $params)調用該函數。現在你可以正常地調用你的函數了(沒有下劃線)。

不過,我不會建議使用__call,除了作爲一種方便。從長遠來看,最好只調用任何你想直接運行的代碼。

+0

是啊,我意識到以後有的用__call篡改,它的設計沒有在我試圖用它的方式來使用。我想我的實際問題是能夠傳遞一個混合值的數組(一些數組,一些字符串等)作爲獨立的參數到被調用的方法。 – machinemessiah 2010-11-04 03:10:25

+0

什麼會阻止你傳遞一個混合值數組作爲參數?這不就是'call_user_func'的用途嗎? – theazureshadow 2010-11-04 03:25:59

+0

不是call_user_func,而是call_user_func_array,前者只是將您的參數數組作爲單個參數(數組),後者解決了我的問題,感謝您向正確的方向推進! – machinemessiah 2010-11-04 03:28:29

1

我更好/更清潔的替代可能是建立一個事件和聽音系統,如Doctrine Events System。 (該代碼實際上來自公共庫,而不是ORM部分。)但是,您將需要所有方法來分派事件。

我儘量避讓使用__call儘可能多的,因爲它使你的代碼更難理解和維護,但我認爲這很好的插件系統中使用。每當你嘗試調用不存在的函數

1

謝謝你的建議,我是一種找錯了樹,但這裏是我想出瞭解決方案:

public function call($method){ 
    //do the something I need to do before method calls 
    $params = func_get_args(); 
    //remove the $method param from the $params array 
    unset($params[0]); 
    return call_user_func_array(array($this,$method),$params); 
} 

再次感謝你們!

0

可以從__call參數直接獲取方法參數:

function __call($method, $args) { 
    return call_user_func_array(array($this,$method),$args); 
}