首页 > 解决方案 > 用 class_alias 覆盖类

问题描述

我知道这是一个非常糟糕的主意,但我的想法已经用完了,所以我想听听一些关于它的意见。

我正在开发一个 PHP 项目,该项目允许开发插件,以便其他开发人员可以添加自己的功能,这与数千个其他开源项目没有太大区别:

root
└── addons
    └── addon-a
    └── addon-b
    └── addon-c

我必须在不更改原始文件或使用Composer PSR-4的情况下对已经制作的插件(比如说插件 A)进行一些更改。不幸的是,原作者没有遵循有助于完成这项任务的良好实践。这是插件 A 的样子:

结构

addon-a
└── main.php
└── classes
    └── Foo.php
    └── Bar.php

插件-a/main.php

include_once __DIR__ . '/classes/Foo.php';
function run() {
    echo AddonA\Classes\Foo::returnTwo();
}

插件-a/classes/Foo.php

namespace AddonA\Classes

use AddonA\OtherFolder\FooBar

abstract class Foo {

    public static function returnTwo() {
        return 2;
    }

    public static function returnFooBar() {
        return new FooBar();
    }

}

我需要重写该returnTwo函数并返回另一个值。在不更改其他文件的情况下,我能够做到这一点的唯一方法是通过class_alias方法,复制整个 Foo 类:

首先,我创建了另一个插件并使其在插件 A“运行”功能之前运行:

结构

new-addon-a
└── main.php
└── classes
    └── Foo.php

新插件-a/main.php

function init() {
    include_once __DIR__ . '/classes/Foo.php';
    class_alias( 'NewAddonA\Classes\Foo', 'AddonA\Classes\Foo', true );
}
init();

new-addon-a/classes/Foo.php

namespace NewAddonA\Classes

use AddonA\OtherFolder\FooBar // No changes to the previous "uses."

abstract class Foo {

    public static function returnTwo() {
        return 3;
    }

    public static function returnBar() {
        return new AddonA\Classes\Bar(); // Here I had to change because the namespace has changed
    }


}

现在,当 Addon A 执行函数run时,这AddonA\Classes\Foo::returnTwo将是我自己的类。


好吧,正如我之前所说,这很丑陋,因为我覆盖了整个类,所以我会丢失对 Foo 代码的任何更新。然而,这是我唯一的想法。您认为可以使用其他方法吗?

谢谢!

标签: phpoverridingcustomization

解决方案


推荐阅读