在构造函数过滤器中扩展/覆盖父级的方法

时间:2019-12-09 05:13:06

标签: php wordpress oop

我正在研究WordPress项目。实现了一个子主题,父主题有一个类来显示作者的链接。我们已经实现了一项功能,每个帖子可以支持多位作者,然后我们有自己的方法来显示适当的链接(不是单作者链接,而是根据作者数来链接许多链接)。

完整场景:

  • 主题:报纸
  • 文件:td_module.php(包括/wp_booster/td_module.php)
  • 类:td_module(抽象,父主题中的许多其他类都继承了这一类)
  • 方法:get_author()
  • 还有许多其他类在父主题中继承了td_module,因此我不能仅在子主题中扩展td_module,因为在更新主题时对父主题的所有更改都会丢失

我需要以某种方式扩展此方法以显示不同的内容,但是我不想更改td_module类中的方法:即使这将是最快/最安全的解决方案,每次升级主题时,代码都会被覆盖

此方法在主题中广泛使用,因此在此处添加一些代码如此重要的原因。

为什么我仍然抱有希望:在td_module类的构造函数上调用了一个WP过滤器td_wp_booster_module_constructor。问题在于,此类在用于显示作者的方法上没有任何其他过滤器,而仅在构造函数上调用了td_wp_booster_module_constructor过滤器。 基本的PHP(和OOP)问题:是否可以通过在构造函数中使用此过滤器来扩展/替换方法?

一些代码需要澄清:

abstract class td_module {
    ...
    function __construct($post, $module_atts = array()) {
        ...
        // Can I change the get_author behavior by using this filter?
        apply_filters("td_wp_booster_module_constructor", $this, $post);
        // This is the only filter available in the entire class!
        ...    
    }
    ...

    function get_author() {
        $buffy = '';
        // Code for generating author link ($buffy .= ...)
        ...
        // This function doesn't have any apply_filter, there are no filters available
        return $buffy;
    }
}

2 个答案:

答案 0 :(得分:1)

基本上,您不能在运行时修改类定义。在构造函数上有一个可用的过滤器的事实是红色的鲱鱼,并且实际上是不相关的。

get_author()可以通过某种方式从外部类定义中更改其行为(在Wordpress中,过滤器和动作挂钩),或者您根本无法做到

在Wordpress之外,在具有适当依赖项反转容器的应用程序中,您可能应该通过decorating the class进行此操作,并让所有类使用者使用修饰的类。

但是,由于您无法告诉类使用者使用另一个类,并且很多代码无法控制就可能直接实例化该类,所以这样的事情就不会实现。


有一个扩展名Runkit,它允许在运行时更改行为和定义。甚至还有一种modify a method definition的方法。尽管我还没有尝试过该扩展,也不知道它是否在更新的PHP运行时中运行。

请注意,在生产代码上执行此操作几乎肯定是一个很糟糕的主意,并且由于您无论如何都无法控制代码,因此您甚至无法确定自己会进行更改首次使用之前的定义。

我还发现a repo for Runkit表示,如果您完全确信这样做,它几乎可以在PHP 7上运行。

答案 1 :(得分:-1)

您的问题是基类是您未编写的供应商代码。

因此,请在您的类之间创建一个扩展类!

工作完成!

<?php

class SomeWordpressCrap
{
    public function doSomething()
    {
        return 'something';
    }
}

class YourAwesomeNewClass extends SomeWordpressCrap
{
    public function doSomething()
    {
        return 'something better!';
    }
}

class OneOfYourExistingClasses extends YourAwesomeNewClass
{

}
  

更新所以事实证明OneOfYourExistingClasses也是供应商代码,因此上述解决方案将不起作用。

但是!您可以使用Roave的“ Better Reflection”库,您可以在https://github.com/Roave/BetterReflection

中找到该库。

这将使您能够“更改函数或方法的主体以执行其他操作”,我相信这正是您所需要的。祝你好运!