2009-07-23 6 views
5

を動的クラスをアンロードします。は、私は次のようにプラグインの動的ロードを実装PHP

function processPlugin($plgFile, $db) { 
    require_once($plgFile); 
    $plgin = new PlginImpl(); 
    $plgin->setDb($db); 
    $ret = $plgin->process(); 
    return $ret; 
} 

を各プラグインが正常に動作しますPlginImplという名前のクラスを定義します。しかし、戻り値process()の範囲内で指定されたプラグインをさらに呼び出すことは可能です。すなわち、上記指定された同じメソッドを呼び出して、しかしで失敗するであろう:

Fatal error: Cannot redeclare class PlginImpl in .. 

すなわち、各プラグインがクラスであることに注意してください:

class PlginImpl extends Plugin implements PluginInterface 

Plugin提供いくつかの有用な機能をPluginInterface、すなわちprocess()を画定します。

私は、すべてのプラグインの名前がPlginImplであるということは、問題を引き起こします。したがって、私の質問は:require_onceをロードした後にクラス(PlginImpl)をアンロードする方法はありますか?あるいは、私が従うべき全く異なるアプローチがありますか?


EDIT 私は次の事を続くせずに試してみました:

  • 解除$plgin__destruct()を呼び出す
  • process()後 - それは processPlugin()内でも process方法
内でもない動作しません。

とても感謝しています!その後、

一時VARに保存されているあなたはplgun-> process()メソッドは、あなたが$ plgin->プロセス(の結果を持っている可能性が http://ca.php.net/manual/en/language.oop5.decon.php

それとも

デコンストラクタを呼び出した時に見えるかもしれません

答えて

10

をロードするためにそれを使用しますクラスをロードした後はクラスをアンロードできないので、各プラグインの名前を変更するだけです。

PluginX、PluginYなどですが、あなたが示したようにプラグインインターフェイスを使用するようにしても問題ありません。特定のプラグインをロードするに

、あなたは単にsolomongabyのようなものが提案するかもしれないが、その代わりに、ファイル名の、あなたが...それをこのような何かプラグインの名前を渡します

function loadPlugin($pluginName) { 
    require_once $pluginName . '.php'; 

    $plugin = new $pluginName; 
    //do whatever with $plugin 
} 
0

)とunset($ plgin)

function processPlugin($plgFile, $db) { 
    require_once($plgFile); 
    $plgin = new PlginImpl(); 
    $plgin->setDb($db); 
    $result = $plgin->process(); 
    unset($plgin); 
    return $result; 
} 

しかし、あなたはおそらく難しい方法で問題に近づいていると思います。

プラグインをクラスにしてから、Implement()をメソッドにする必要があります。

+0

上述したように私が解除使用しようとしたが、それだけPlginImplのインスタンスをアンロードするが、定義がメモリ(第2ランfailes)に留まります。デコンストラクタも動作しません。 – MrG

0

私はプラグインの読み込み

class pluginLoader { 
    protected $_plugins = array(); 
    protected $_db; 

    public function setDB($db) { 
    $this->_db = $db; 
    } 


    public function load($plgFile) { 
    if (!isset($this->_plugins[$plgFile])) { 
     require_once($plgFile); 
     $plgin = new $plgFile(); 
     $plgin->setDb($this->_db); 
     $this->_plugins[$plgFile] = $plgin; 
    } 
    $this->_plugins[$plgFile]->process(); 
    } 

    public static function instance($db) { 
    static $instance; 

    if (!$instance instanceof self) { 
     $instance = new self($db); 
    } 
    return $instance; 
    } 
} 

を扱うためのクラスになるだろうし、あなたが最初

pluginLoader::instance($db); 

を行うだろうと、プラグイン

pluginLoader::instance()->load($plgFile); 
+0

多くのありがとうございます - しかし、私はすべてのプラグインが "PlginImpl"と呼ばれているという事実のため、これまでとまったく同じ問題に遭遇しませんでしたか? – MrG

+0

上記の解決策と組み合わせて、クラスファイルのプラグイン名を使用してください –

1

を私はしませんよ100%確信していますが、クラスが宣言されたらクラスをアンロードすることはできません。

しかし、です。あなたがしようとしていることを達成する方法です。

名各クラスは異なると次を作成する前に、1つのクラスを破壊する:

$class1 = "foo"; 
$class2 = "bar"; 

$pluginResult = processPlugin($class1); 
// do stuff 
$pluginResult = processPlugin($class2); 

function processPlugin($pluginName, $db) { 
    require_once($pluginName . ".inc"); //or whatever scheme you want to use. 
    $plgin = new $plugin; 
    $plgin->setDb($db); 
    $ret = $plgin->process(); 
    unset($plgin); 
    return $ret; 
} 

あなたは、いくつかの余分な定義されたクラスの周りにぶら下がって、うまくいけば、メモリの問題を最小限に抑える必要があり、一度ロードされたプラグインを設定解除する必要があります。

4

別のオプションは、私はそれをお勧めしませんが、runkit_importを使用することです。

+1

これについては分かりませんでした。クール:) – AntonioCS

1

私が知っている私は、このログはhow'llは、将来的に同じ問題を抱えて助けることができることを願って、質問は何年も前に掲示されてきたが、私は今日、この問題に墜落しました。

it'hasは、多くの回答で述べられているように、PHPは(少なくとも5.3まで)のクラスをアンロードすることはできません。名前間の衝突を避けることができます。これを念頭に置いて、各プラグインを一意の名前空間にロードするコードを記述しました。

$uniqueContext = 'Context_'.rand(); 
$content = file_get_contents($actionScript); 
if (strstr($content, '<?php')) { 
    $content = str_replace('<?php', "<?php namespace $uniqueContext;", $content); 
} else { 
    if (strstr($content, '<?')) { 
     $content = str_replace('<?', "<?php namespace $uniqueContext;", $content); 
    } else { 
     $content = "namespace $uniqueContext;".$content; 
    } 
} 
$tmp=array_search('uri', @array_flip(stream_get_meta_data($GLOBALS[mt_rand()]=tmpfile()))); 
file_put_contents($tmp, $content); 
require_once($tmp); 

プラグインの作者は、参照されるクラスは、ホストがそのコンテキストに対して作成するコンテキストに関連していることを意識する必要があります。

+0

PHP 5.3までは、クラスをアンロードすることができません。どのようにPHP 5.3でそれを行うには? – chiliNUT

関連する問題