Hy there. I'm developing plug-in system and I have problems with call_user_func and referenced variables.
I'm calling plug-in handler like this:
if(PluginFactory::NumberOfPlugins() != 0)
foreach(PluginFactory::GetPlugins() as $pPlugin)
call_user_func(get_class($pPlugin) . "::OnHandlePluggablePart", "Core:AfterSceneAssembly", $Document);
Where $Document
is my document object where I hold my controls. The idea is that plug-ins can modify control set (add, delete, modify). My plugin class is this:
class SomePlugin extends Plugin
{
...
public static function OnHandlePluggablePart($sPart, &$Document)
{
if($sPart == "Core:AfterSceneAssembly")
{
开发者_运维技巧 $Document->AddControl(new Paragraph("", "Plugin test"));
}
}
}
Document object is passed by value (copied) not reference... What to do, what to do :) ?
Try that:
if(PluginFactory::NumberOfPlugins() != 0)
foreach(PluginFactory::GetPlugins() as $pPlugin) {
$class = get_class($pPlugin);
$class::$transport = &$Document;
call_user_func( $class."::OnHandlePluggablePart", "Core:AfterSceneAssembly");
}
class Plugin {
public static $transport;
...
}
class SomePlugin extends Plugin {
...
public static function OnHandlePluggablePart($sPart) {
if($sPart == "Core:AfterSceneAssembly") {
self::$transport->AddControl(new Paragraph("", "Plugin test"));
}
}
}
Here's a self-contained example that works fine with php5 and uses (most of) your code from the question.
<?php
echo 'phpversion: ', phpversion(), "\n";
$Document = new MyDocument;
if(PluginFactory::NumberOfPlugins() != 0)
foreach(PluginFactory::GetPlugins() as $pPlugin)
call_user_func( get_class($pPlugin) . "::OnHandlePluggablePart", "Core:AfterSceneAssembly", $Document);
foreach( $Document->a as $a ) {
echo '# ', $a, "\n";
}
class MyDocument {
public $a = array();
public function AddControl($s) {
$this->a[] = $s;
}
}
class PlugA {
public static function OnHandlePluggablePart($sPart, $Document) {
$Document->AddControl('PlugA-Control');
}
}
class PlugB {
public static function OnHandlePluggablePart($sPart, $Document) {
$Document->AddControl('PlugB-Control');
}
}
class PluginFactory {
static $p = null;
public static function NumberOfPlugins() {
self::foo(); return count(self::$p);
}
public static function GetPlugins() {
self::foo(); return self::$p;
}
public static function foo() {
if ( is_null(self::$p) ) {
self::$p = array(new PlugA, new PlugB);
}
}
}
prints
phpversion: 5.3.3
# PlugA-Control
# PlugB-Control
精彩评论