close
算是在實做過程中發現一些問題,然後重構這個強力工具!
我知道我目前碰到一個危險的境界,由於這個插件的類別非常強力,我經常拿他來替代繼承,我知道有點過頭了,但它真的很好用!
~我是說你可以維持一個物件變數,然後把需要功能一直掛入(只要你繼承這個抽象的插件類別,寫出你需要的功能)~
這幾天一直為了unset前後記憶用量沒有改變的問題無法釋懷,後來問了 kiang,他表示那是 Zend 引擎還沒到記憶體回收的週期,所以不會釋放~
這個類別的 __更新() 方法有一個地方我一直無法瞭解為何會有這個效果,知道的網友請開示吧~
另外一提,ADODB Lite 目前仍然是記憶用量最小的 DB Layer ,我自己寫的這個 DB Layer 跟它比較,兩邊都不掛任何多餘的模組,硬是比它大了約 50 K...
我該檢討了~
<?php
abstract class Zyme_Class_Plugin{
private $_插件 = array();
private $_方法 = array();
private $_反映 = array();
function __construct($宿主 = null){
static $類別 = __CLASS__;
if ($宿主 instanceof $類別) {
$this->__插件($宿主);
}
}
final function __call($方法, $參數){
return call_user_func_array($this->_方法[$方法], $參數);
}
// 清除插件方法
final protected function __清除(){
$this->_插件 = array();
$this->_方法 = array();
$this->_反映 = array();
}
// 測試某個插件是否已安裝
final protected function __已裝($類別){
return isset($this->_插件[$類別]);
}
// 將插件的方法加入$this的方法中
final protected function __插件(Zyme_Class_Plugin $插件){
$類別 = get_class($插件);
if (false == $this->__已裝($類別)){
$this->_插件[$類別] = $插件;
$this->_方法 = $插件->__反映() + $this->_方法;
}
}
// 取得插件的可呼叫方法列表
final function __方法(){
return $this->_方法;
}
// 取得插件本身的方法列表(除了方法名稱開頭是'__'的方法,例如一些魔術方法,或是方法本身屬於私有方法)
final private function __反映(){
$輸出 = &$this->_反映;
if (false == empty($輸出)) {
return $輸出;
}
$反映 = new ReflectionObject($this);
$方法 = $反映->getMethods();
foreach ($方法 as $項目){
$名稱 = $項目->getName();
if (0 !== strpos($名稱, '__') && false == $項目->isPrivate()) {
$輸出[$名稱] = array($this, $名稱);
}
}
return $輸出;
}
// 匯入插件的可呼叫方法表
final function __匯入(Zyme_Class_Plugin $宿主){
$this->_方法 = $宿主->__方法() + $this->_方法;
}
// 更新所有插件的方法,通常在載入所有插件後調用
final protected function __更新(){
foreach ($this->_插件 as $插件){
$插件->_方法 = $this->_方法 + $插件->_方法; // 照理說,這行應該會出現錯誤(存取私有成員),但不知為何可以執行
// $插件->__匯入($this); // 萬一未來版本上面那行無法執行時,可以改用這行
}
}
}
?>
我知道我目前碰到一個危險的境界,由於這個插件的類別非常強力,我經常拿他來替代繼承,我知道有點過頭了,但它真的很好用!
~我是說你可以維持一個物件變數,然後把需要功能一直掛入(只要你繼承這個抽象的插件類別,寫出你需要的功能)~
這幾天一直為了unset前後記憶用量沒有改變的問題無法釋懷,後來問了 kiang,他表示那是 Zend 引擎還沒到記憶體回收的週期,所以不會釋放~
這個類別的 __更新() 方法有一個地方我一直無法瞭解為何會有這個效果,知道的網友請開示吧~
另外一提,ADODB Lite 目前仍然是記憶用量最小的 DB Layer ,我自己寫的這個 DB Layer 跟它比較,兩邊都不掛任何多餘的模組,硬是比它大了約 50 K...
我該檢討了~
<?php
abstract class Zyme_Class_Plugin{
private $_插件 = array();
private $_方法 = array();
private $_反映 = array();
function __construct($宿主 = null){
static $類別 = __CLASS__;
if ($宿主 instanceof $類別) {
$this->__插件($宿主);
}
}
final function __call($方法, $參數){
return call_user_func_array($this->_方法[$方法], $參數);
}
// 清除插件方法
final protected function __清除(){
$this->_插件 = array();
$this->_方法 = array();
$this->_反映 = array();
}
// 測試某個插件是否已安裝
final protected function __已裝($類別){
return isset($this->_插件[$類別]);
}
// 將插件的方法加入$this的方法中
final protected function __插件(Zyme_Class_Plugin $插件){
$類別 = get_class($插件);
if (false == $this->__已裝($類別)){
$this->_插件[$類別] = $插件;
$this->_方法 = $插件->__反映() + $this->_方法;
}
}
// 取得插件的可呼叫方法列表
final function __方法(){
return $this->_方法;
}
// 取得插件本身的方法列表(除了方法名稱開頭是'__'的方法,例如一些魔術方法,或是方法本身屬於私有方法)
final private function __反映(){
$輸出 = &$this->_反映;
if (false == empty($輸出)) {
return $輸出;
}
$反映 = new ReflectionObject($this);
$方法 = $反映->getMethods();
foreach ($方法 as $項目){
$名稱 = $項目->getName();
if (0 !== strpos($名稱, '__') && false == $項目->isPrivate()) {
$輸出[$名稱] = array($this, $名稱);
}
}
return $輸出;
}
// 匯入插件的可呼叫方法表
final function __匯入(Zyme_Class_Plugin $宿主){
$this->_方法 = $宿主->__方法() + $this->_方法;
}
// 更新所有插件的方法,通常在載入所有插件後調用
final protected function __更新(){
foreach ($this->_插件 as $插件){
$插件->_方法 = $this->_方法 + $插件->_方法; // 照理說,這行應該會出現錯誤(存取私有成員),但不知為何可以執行
// $插件->__匯入($this); // 萬一未來版本上面那行無法執行時,可以改用這行
}
}
}
?>
全站熱搜
留言列表