OOP PHP — 如何有选择地调用类构造函数中定义的特定方法?

OOP PHP — How to selectively call a specific method defined in a class' constructor?

提问人:grazdev 提问时间:10/6/2017 最后编辑:grazdev 更新时间:10/6/2017 访问量:336

问:

我正在学习以 OOP 方式编写 Wordpress Multisite 代码,由于我现在对 OOP 很陌生,所以我似乎无法自己解决这种情况。

具体来说,我正在创建一些类,以使用 OOP 方法创建管理页面(在网络和子站点级别)。这是我的简化代码:

class AdminPage {

    public function __construct( $args ) {
        add_action( 'admin_menu', array( $this, 'add_admin_page' ) );
    }

    public function add_admin_page() {
        add_menu_page( // arguments );
    }

}

class AdminNetworkPage extends AdminPage {

    public function __construct( $args ) {
        add_action( 'network_admin_menu', array( $this, 'add_admin_page' ) );
     }

}

代码有效,但正如您所看到的,我必须扩展 AdminPage 类,其唯一目的是更改构造函数中的钩子(我需要网络级别的管理页面而不是)。admin_network_menuadmin_menu

有没有更好的方法可以做到这一点?一种方法是拥有一个类,将两个钩子放在该类的构造函数中,然后有选择地调用其中一个或另一个?

不幸的是,创建类 () 的新实例,然后对其调用方法(例如 ) 在这种情况下不起作用,因为这样我就收到一个错误说 is undefined...这一切都必须在构造函数中发生。$page = new AdminPage$page->add_admin_page()add_menu_page

php wordpress 哎呀

评论

2赞 deceze 10/6/2017
你不能进入一个函数的内部,只执行它的一部分,不。您可以像您一样替换整个函数,或者使用函数参数来影响函数的功能。
0赞 grazdev 10/6/2017
@deceze 感谢您的参与。因此,如果我理解正确,我唯一的选择而不是覆盖是将参数传递给构造函数,例如“site_level”,如果它的值是“network”,则做一个钩子,如果值是“子网站”,则执行另一个钩子。这是对的吗?以这种方式覆盖或传递参数哪个会更好?
1赞 BeetleJuice 10/6/2017
如果您知道参数,我会传递一个参数,并在实例化类时控制它。这将使我能够避免不必要地复制代码。
0赞 axiac 10/6/2017
“一种方法是拥有一个类,将两个钩子放在该类的构造函数中,然后有选择地调用其中一个或另一个?”-- 绝对不!一个类必须只有一个存在的理由。

答:

0赞 Sean 10/6/2017 #1

你可以做这样的事情:

class AdminPage {

    public function __construct( $args, $networkPage = false ) {

        if($networkPage) {

            add_action( 'network_admin_menu', array( $this, 'add_admin_page' ) );

        } else {

            add_action( 'admin_menu', array( $this, 'add_admin_page' ) );

        }

    }

    public function add_admin_page() {

        add_menu_page( // arguments );

    }
}

然后将第二个参数传递给类以更改您添加的操作,例如

$page = new AdminPage($args);
$networkPage = new AdminPage($args, true);

这是否比仅仅扩展类更好是值得商榷的;我个人认为你的初始设置没有错,OOP 的重点不是创建尽可能少的类 - 如果你的代码作为两个单独的类更有意义(一个扩展另一个),那么这没有错。

评论

0赞 deceze 10/6/2017
我可能宁愿和,......__construct($action = 'admin_menu')add_action($action, ...)
1赞 grazdev 10/6/2017
我会接受这个答案,因为它给出了另一个可用选项(在构造函数中传递参数)的示例,@deceze对我的问题的评论中已经提出了这个选项。