call_user_func и переменные по ссылке - PullRequest
1 голос
/ 01 октября 2010

Хай там. Я разрабатываю систему плагинов, и у меня проблемы с call_user_func и ссылочными переменными.

Я называю обработчик плагина следующим образом:

    if(PluginFactory::NumberOfPlugins() != 0)
    foreach(PluginFactory::GetPlugins() as $pPlugin)
        call_user_func(get_class($pPlugin) . "::OnHandlePluggablePart", "Core:AfterSceneAssembly", $Document);

Где $Document - это объект моего документа, где я храню свои элементы управления. Идея заключается в том, что плагины могут изменять набор элементов управления (добавлять, удалять, изменять). Мой класс плагинов такой:

class SomePlugin extends Plugin
{

    ...

    public static function OnHandlePluggablePart($sPart, &$Document)
    {
        if($sPart == "Core:AfterSceneAssembly")
        {
            $Document->AddControl(new Paragraph("", "Plugin test"));
        }
    }
}

Объект документа передается по значению (копируется), а не по ссылке ... Что делать, что делать :)?

Ответы [ 2 ]

2 голосов
/ 01 октября 2010

Попробуйте это:

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"));
        }
    }
}
0 голосов
/ 01 октября 2010

Вот отдельный пример, который отлично работает с php 5 и использует (большую часть) ваш код из вопроса.

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

печать

phpversion: 5.3.3
# PlugA-Control
# PlugB-Control
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...