gpt4 book ai didi

php - 一个php插件架构

转载 作者:可可西里 更新时间:2023-11-01 12:35:46 25 4
gpt4 key购买 nike

我正在想办法为我自己的框架创建一个插件架构。我已经阅读了许多主题并在此处和其他网站上发帖。基本上我已经找到了以下解决方案,这似乎是 PHP 中唯一的好选择(目前)。

这个想法是每个类都扩展了一种类似类的观察者。所以模板类、BaseController 等总是扩展插件类。

class BaseController extends Plugin
{
public function __construct()
{
// Plugin check, notify all loaded plugins
$this->checkForEarlyHooks();

// Init some standard stuff
$this->view = new Template();
$this->baseLayout = 'layout.html';

$this->something = new Something();

// Plugin check, notify all loaded plugins
$this->checkForLateHooks();
}
}

所以这里基本上发生的是,当 indexController 扩展 baseController 时,插件检查就完成了。在这种情况下为构造函数。当您想在实际调用 Action 方法之前使用插件进行某种登录检查时,这会很方便。

Plugin 类可以从调用的类中解析出来,并知道要在加载的插件中查找哪些函数。

另请注意,它会检查加载的插件列表 2 次。在构造函数中加载任何内容之前(早期),以及在加载所有变量时(晚期)。

我还可以向“checkForLateHooks()”函数添加变量。所以钩子(Hook)函数也可以操作它们,比如“baseLayout”变量。

一个钩子(Hook)函数看起来像这样:
public function hookConstruct ( &$baseLayout )
{
$baseLayout = 'login.html';
}

现在基本上我的问题是,这种方法有什么好处吗?我知道可能还有很多其他方法可以做到这一点。但我主要不想以后遇到设计问题。现在看来是个好主意,但你永远不知道以后会如何……

如果我没记错的话(从我读过的所有帖子中),这有点像 WordPress(以及其他一些框架)。

最佳答案

更新 :现在的回答反射(reflect)了最新的链接和更好的描述。

设计插件系统当然有很多不同的方法,也许可以在 https://softwareengineering.stackexchange.com/ 上询问。会给你更多的想法,但我会尝试通过分享我的想法和经验来帮助你。

我将分享一些我自己的经验,这些经验是我通过一系列自己的框架学到的。当前 Agile UIAgile Data两者都支持许多需要扩展的内容,但我将专注于“组件”

Hook

当您希望将代码注入(inject)现有对象时,钩子(Hook)是一种标准方法。这是使用既定结构扩展应用程序或流程的最佳选择。

在重构我的框架时,我将钩子(Hook)实现分离到一个单独的特征中并记录在此处:http://agile-core.readthedocs.io/en/develop/hook.html

主机应用:

... some code here ..
$this->hook('beforeInit');
$this->init();
$this->hook('afterInit');
... code goes on ..

插入:
$host_app->addHook('beforeInit', function($object) {
echo "About to execute init of $object";
});

用户界面组件

组件呈现不同的设计模式,适用于用户界面。您从页面/应用程序布局开始,然后将其分解为菜单、页眉、页脚和内容。

组件是可以与布局或其他组件相关联的对象。每个组件都能够渲染和传递额外的 HTML/JS 给它的父组件。大多数组件也将是一个交互式对象。

这种方法称为“渲染树”,应用程序执行经历两个阶段——“渲染树的初始化”和“渲染”。

主机应用:
$layout->menu = new \atk4\ui\Menu();
$layout->add($layout->menu, 'TopMenu');

上面的代码展示了如何初始化一个新的组件(菜单)并将其插入到 $layou 中。 .此外,$menu 的 HTML 输出被定向到 {$TopMenu} 标签中,该标签在 Layout 的 HTML 模板中定义。

插件可以通过以下方式与渲染树交互:
  • 在树中的任意位置添加更多组件
  • 影响现有组件(例如添加新菜单项)
  • 破坏任何现有组件

  • 当这些方法结合在一起时,您可以使用以下方法:
    $app->addHook('afterInitLayout', function($app) {

    $app->layout->menu->destroy(); // remove default menu
    $app->layout->menu = new \plugin\SuperMenu();
    $app->layout->add($app->layout->menu);
    });

    这可用于使用附加组件中更强大的实现来替换标准菜单。

    我的组件实现记录在这里:

    http://agile-ui.readthedocs.io/en/latest/view.html#initializing-render-tree

    用户界面/数据分离

    虽然对于一个问题可能没有那么多答案,但另一种强大的扩展方式是关注点分离。 Agile UI 中的所有 UI 组件不知道如何处理数据。

    虽然许多 UI 生成器需要开发人员手动构建它们并与数据链接,但我正在注入(inject)“模型”对象,如下所示:
    $form->setModel(new User($db)); // populates name, surname and gender fields

    演示: http://ui.agiletoolkit.org/demos/form2.php (第二种形式)

    在这种方法对象 User包含足够的元数据供表单填充其字段、标题执行验证以及保存/加载数据。

    由于“用户”类也可以在附加组件中声明,因此通过添加对新数据实体的支持,它提供了一种非常强大的扩展现有功能的方法。

    其他方法

    使用附加组件进行扩展的其他一些方法包括:

    工厂:

    将指定为字符串的类解析为命名空间/文件的能力:
    $api->add('MyClass');

    为附加组件提供重新路由标准类的能力,但对 IDE 中的类型提示不是很友好。

    新类型/特性:

    附加组件可以提供添加持久性、表列、表单字段、操作等的新类。

    结论

    我认为附加设计归结为:
  • 安装和使用简单
  • 附加组件需要开箱即用吗?
  • 避免附加组件之间的冲突
  • 定义不同的加载项类型 - 身份验证、UI、行为
  • 可以附加组件扩展另一个附加组件
  • 附加组件是否适合应用程序设计、数据和架构?
  • 在不牺牲性能的情况下为附加组件提供大量功能
  • 关于php - 一个php插件架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10053479/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com