【问题标题】:Design pattern for implementing plugins in PHP applications在 PHP 应用程序中实现插件的设计模式
【发布时间】:2012-03-03 21:33:24
【问题描述】:

对于如何在 PHP 应用程序中实现插件是否有共识?

我查看了接近的observer pattern,它实际上只是一个通知系统,不允许代码直接扩展应用程序。我目前正在使用我想出的一个简单的钩子系统:

public function registerHook($hookName, array $params = array())
{
    $this->hooks[] = $hookName;

    foreach ( $this->plugins as $pluginName => $hooks ) {
        if ( in_array($hookName, $hooks) ) {
            $plugin = new $pluginName($this, $this->view, $this->controller);

            $plugin->{$hookName}($params);
        }
    }
}

这对我的目的很有效,但我很好奇是否有一种设计模式已经过多次测试和证明,而我只是在重新发明轮子。

【问题讨论】:

  • 我建议看看它是如何与 Wordpress 一起工作的。我不了解自己,但我感觉它在使用钩子,而 BOY 确实 wordpress 有很多插件。好问题,赞成。
  • @Relequestual 我熟悉 WordPress,他们采用“操作”的程序方法。 codex.wordpress.org/Function_Reference/add_action
  • 我想说这个问题不是骗人的,但在某种程度上它是。似乎在这里讨论了共识stackoverflow.com/questions/42/…
  • 我读过,但这是一个旧线程。 PHP 5.3 有许多可以利用的 OO 特性。
  • 使用观察者模式,您可以/需要在您希望能够扩展代码的位置激活观察者。 IE。你需要有指定的触发点,在这些触发点上你会碰到你的观察者,并让他们告诉你是否还有其他事情需要做。绝对不是插入代码的最干净的方式。

标签: php oop design-patterns plugins observer-pattern


【解决方案1】:

我认为 Events Dispatcher 是实现插件或任何扩展的好方法。 Events Dispatcher 是 Observer 模式的一种实现,并在 symfony、Symfony2Zend Framework 2(测试版)中使用。

浏览 github 上的任何一个源代码都会带来一些有趣的阅读。不过,可以在这里找到一些有趣的信息:

http://components.symfony-project.org/event-dispatcher/trunk/book/02-Recipes

几年前我为一个项目编写了一个事件和钩子类,如果我能找到它,我会在这里发布。

【讨论】:

  • 我想你从来没有找到它:)
  • 是的,他从来没有找到它:-)
  • 不,从未找到。 :)
  • 请找到它... :)
  • 搜索仍在进行中。
【解决方案2】:

你用钩子实现的方式也是我实现它的方式。

您的示例最大的问题是您的函数实例化了插件。为什么不传递插件的实例呢?

我这样做的方式是先实例化一个插件,然后自己注册它的钩子。

【讨论】:

  • 一个插件可以实现多个钩子,为每个钩子创建一个新实例以避免共享状态。
  • 共享状态是插件本身应该知道的。如果您需要单独的状态,请使用多个对象。
  • 为什么这是个问题?它使钩子实现分离,无需跟踪插件实例。
  • 您失去了 OOP 提供的许多功能。通过这样做,您可以有效地将对象视为静态对象。如果您想了解更多相关信息,请查找“依赖注入”。只是一般的设计模式也将是有益的。尽管现在这似乎不是问题,但我保证将来你会看到这是不灵活的..
【解决方案3】:

Zend 框架使用 dispatchLoopStartup() 和 dispatchLoopShutdown() 钩子作为类方法。 每个插件都是一个实现上述方法的类。

ZF manual reference

【讨论】:

    【解决方案4】:

    没有银弹意义上的共识。对于已建立的模式,您有多种选择,例如

    仅举几例。

    您使用哪一个取决于您,但您应该确保您的系统架构支持模块化。查看这些幻灯片以了解一些想法

    【讨论】:

    • @Gordon 对于装饰主“应用程序”对象(如 silex 所具有的)、对其进行修改然后返回它,您有什么看法?然后你可以反复装饰这些,为每个新的应用程序修改添加更多的装饰器,并且可以随时删除每个装饰器而不影响其余部分?
    • @Jimbo 当然,如果那是你想做的。但请记住,装饰器通常只对装饰类的现有 API 进行操作。你也可以使用Silex before() and after() hooks
    【解决方案5】:

    嗯,在Wikipedia article about Plugin concept 中有一个名为jin-plugin 的项目的链接。我也是第一次看到这个框架,但是,也许你可以马上使用它。

    此外,你真的应该用谷歌搜索“插件模式”之类的东西,我在第一页上只找到了两个链接:Plug-in PatternExtensibility pattern (wikipedia)

    如果它真的是一种模式,那么它应该与语言无关,因此您可以安全地从任何语言中获取任何现有的解决方案并将其转换为 PHP。

    P。 S. 谢谢你的提问,不管怎样,你确实让我对这个话题产生了兴趣。 ;)

    【讨论】:

      【解决方案6】:

      看看 Yii 框架。 Yii 严重依赖事件,这些事件比钩子、动作等更干净。使用事件,您可以允许系统的不同部分以面向对象的方式相互通信。

      【讨论】:

      • 我并不是真的在寻找代码示例,但我会看看,谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多