算是在實做過程中發現一些問題,然後重構這個強力工具!

我知道我目前碰到一個危險的境界,由於這個插件的類別非常強力,我經常拿他來替代繼承,我知道有點過頭了,但它真的很好用!
~我是說你可以維持一個物件變數,然後把需要功能一直掛入(只要你繼承這個抽象的插件類別,寫出你需要的功能)~

這幾天一直為了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);    //    萬一未來版本上面那行無法執行時,可以改用這行
        }
    }
   
}

?>


創作者介紹

失落的技術

HACGIS 發表在 痞客邦 PIXNET 留言(4) 人氣()


留言列表 (4)

發表留言
  • jaceju
  • > 照理說,這行應該會出現錯誤(存取私有成員),但不知為何可以執行

    類別可以在自己的 Scope 中存取以該類別生成的實體的私有成員。例如:
    <pre>
    <?php

    class A
    {
    private $_a;

    private $_inside = 123;

    public function test()
    {
    $this->_a = new A();
    echo $this->_a->_inside; // 可以存取,沒問題
    }
    }

    $a = new A();
    $a->test();
    </pre>
  • jaceju
  • 再舉個例子,這個比較像你上面的插件: [我不知道要怎麼在留言裡呈現程式碼 :( ]

    [code]
    <?php

    class A
    {
    private $_inside = 123;

    public function test(A $a)
    {
    echo $a->_inside; // 沒問題
    }
    }

    $a1 = new A();
    $a2 = new A();
    $a1->test($a2);
    [/code]
  • HACGIS
  • 我想這算是 PHP 的特性吧,目前可以這樣用就好~

找更多相關文章與討論