Unload a dynamic class in PHP

I implemented dynamic loading of plugins as follows:

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

Each plugin defines a class with a name PlginImplthat works great. But it should be possible to call additional plugins specified within the return value process(). This would invoke the same method above, but not with:

Fatal error: Cannot redeclare class PlginImpl in ..

Please note that each plugin is a class, namely:

class PlginImpl extends Plugin implements PluginInterface

PluginIt offers several useful features while PluginInterfacedetermines, for example process().

I assume that the fact that all plugins are called PlginImpl is causing a problem, so my question is: is there a way to unload class ( PlginImpl) after loading it from require_once? Or should I follow a completely different approach?


EDIT I tried without success the following things:
  • $plgin after process()
  • call __destruct()- it does not work either inside processPlugin()or inside the methodprocess
+7
source share
6 answers

Since you cannot unload a class after loading it, the only option you have is to rename each plugin.

PluginX, PluginY, etc., but that doesn’t matter, because you can just get them to use the plugin interface, as you showed.

To load a specific plugin, you could just have something like a straw, but instead of a file name, you pass it the name of the plugin .. something like this:

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

    $plugin = new $pluginName;
    //do whatever with $plugin
}
+11
source

Another option, although I do not recommend it to use runkit_import .

+4

100%, , .

, .

- :

$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;
}

, , , , .

+1

, , , , , .

, 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);

, , .

+1

You can see how the plgun-> process () method calls the deconstructor http://ca.php.net/manual/en/language.oop5.decon.php

or

You can have the result $ plgin-> process () stored in temp var and then unset ($ plgin)

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

However, I think that you are probably very difficult to approach the problem.

Perhaps you have a class plugin, and then the Implement () method is the method.

0
source

I would make a class to handle loading plugins

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;
  }
}

and to use it you will first do

pluginLoader::instance($db);

and then download the plugin

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

All Articles