首页  >  问答  >  正文

扩展内部使用的 PHP 类而不更改依赖项

我想重写 Laravel 中的 PHP 类,但是它正在被其他几个我不想打扰的类扩展。总体结构如下

class A extends R { }
class B extends R { }
class C extends R { }
class D extends R { }

其中 A/B/C/D/R 是外部包中的所有类。

我想将 A/B/C/D 扩展到 P 而不更改任何这些文件(这将成为维护负担),这样 P 类扩展了 R。因此,我可以对 P 类进行添加。

我一直在研究class_alias(),它允许我连接到自动加载器。这会正确加载类 P

我使用的代码是:

// Some bootstrap file:
class_alias(
    P::class,
    R::class
);
// My modification:
class P extends R
{
    // ...
}

但是我遇到了错误:

ErrorException:无法声明类 R,因为该名称已在使用中

我正在寻找一种解决方案,可以扩展内部 PHP 类,同时防止复制类的完整文件内容。我什至不知道是否可以做到。我想要扩展的类不适合 Laravel 服务容器,因此没有第一方方法来添加功能。

P粉278379495P粉278379495306 天前336

全部回复(1)我来回复

  • P粉189606269

    P粉1896062692024-01-11 00:08:07

    class_alias 本身还不够,因为为了让 P 扩展 R,两个类都必须存在。而class_alias与自动加载无关,它只是声明一个具有两个名称的类。

    您实际需要的是使用新名称定义真正的类 R,然后使用名称 R 定义您自己的类(您实际上不需要 class_alias)。

    一种方法是动态重写目标类的源代码,然后加载修改后的副本,如下所示(未经测试):

    $code = file_get_contents(__DIR__ . '/vendor/path/to/R.php');
    $code = str_replace('class R', 'class R_original', $code);
    eval($code);
    
    class R extends R_original {
       // Your code here
    }

    重要的是,这需要在普通自动加载器尝试定义类之前运行。例如,您可以使用 spl_autoload_register,其中 $prepend 选项设置为 true

    回复
    0
  • 取消回复