【问题标题】:How to extend a php class with more classes如何用更多类扩展一个 php 类
【发布时间】:2011-06-11 13:17:46
【问题描述】:

我想知道这是否是一种获得你所看到的东西的方法

class main_class extends main_class {...}

但是 php 并不高兴。 :(

然后我想问一下stackoverflow,我相信有人会知道解决方案。 经过几个小时的调试,我只用一点代码就自行解决了问题。

问题在于class some_class 不允许您覆盖现有类,所以我需要做的是使用 __get 和 __call 并将另外 2 行添加到我的 __construct 函数中。

这是我解决的代码:

class main_class {
    private $_MODS = array(),...;
    public ...;
    public function __construct(...) {
        ...
        global $MODS_ENABLED;
        $this -> $_MODS = $MODS_ENABLED;
    }
    ...
    public function __get( $var ) {
        foreach ( $this->_MODS as $mod ) 
            if ( property_exists( $mod, $var ) )
                return $mod -> $var;
    }
    public function __call( $method, $args ) {
        foreach ( $this->_MODS as $mod )
            if ( method_exists( $mod, $method ) )
                return call_user_method_array( $method, $mod, $args );
    }
}

然后只需运行它来扩展我的 main_class 而不覆盖原始函数,因此它让我运行我的新函数,但如果需要,我可以获取原始函数:

$MODS_ENABLED=array();
class mod_mail {...}
$MODS_ENABLED[]=new mod_mail;

现在让我们加载我们的类并从我们的 mod 中运行一个函数:

$obj = new main_class(...);
$obj -> mail("root@localhost", "me@me.me", "Testing a mod.", "This email was sent via My main_class but this is a mod that extended main_class without renaming it.");

好吧,我的 mod 不是用于发送电子邮件,而是将子域重定向到别名路径名,但您理解此处显示的概念。

编辑:解决问题后,我看到一条评论说可能存在重复,所以我检查了一下,发现其他人有非常相似的解决方案,但请不要将其标记为当他询问添加到已经构建的类时,我想在构建时覆盖函数。我的解决方案接受了一组构造类并将它们“合并”到我的 main_class 中,该方法确实保留了原始函数,但我也可以使用另一个函数调用原始函数来绕过 __call 函数。

感谢所有发布答案的人。

【问题讨论】:

  • 我想要一个 mods 目录,它可能启用了 mods,也可能没有启用它们。我不能真正扩展一个类,然后再扩展一个类,并确保所有修改都已更改。
  • 如果你能运行class test extends test {...},那该多好啊
  • 你还有其他方法吗?
  • @Gordon,嗯,正确但不正确,他们要求将事物添加到类动态中,我要求合并,相似但不一样。合并将允许我在保留原件的同时覆盖函数,好吧,他们发布的答案恰好与我的解决方案相似,但我的解决方案不需要我将类注册到原件中,而是我的解决方案从现有数组中获取所有内容,两者都工作,两者都是好方法,我将在“可能重复”中发布我的答案。它们不一样,我将编辑我的问题以回答原因。

标签: php class join merge


【解决方案1】:

在 C# 中,您可以通过定义 partial class 来做到这一点。这基本上就像在不同的文件中编写更多相同的类。我不确定 PHP 是否支持这一点,但这篇文章可能会有所帮助?

http://www.toosweettobesour.com/2008/05/01/partial-classes-in-php/

【讨论】:

  • 我真正追求的是将 2 个或多个类合并为一个,这只对一个类有好处。 :(我知道我可以修改它来工作但是让我们看看是否有人知道更好的方法。:)
  • 提供了一个非常好的链接。谢谢你!
  • 我认为没有办法合并类。您应该只使用扩展类。
  • +1 解决方案,虽然它不是我想要的,但如果我在回答我的问题之前完整阅读它,它会为我节省几个小时。
【解决方案2】:

自行解决:) 我已经自己解决了这个问题,我相信其他人会发现它很有用,所以这是我的 php 代码。

class main_class {
    private $_MODS = array(),...;
    public ...;
    public function __construct(...) {
        ...
        global $MODS_ENABLED;
        $this -> $_MODS = $MODS_ENABLED;
    }
    ...
    public function __get( $var ) {
        foreach ( $this->_MODS as $mod ) 
            if ( property_exists( $mod, $var ) )
                return $mod -> $var;
    }
    public function __call( $method, $args ) {
        foreach ( $this->_MODS as $mod )
            if ( method_exists( $mod, $method ) )
                return call_user_method_array( $method, $mod, $args );
    }
}

然后简单地运行:

$MODS_ENABLED=array();
class mod_mail {...}
$MODS_ENABLED[]=new mod_mail;

现在你需要做的就是通过调用你的主类。

$obj = new main_class(...);
$obj -> mail("root@localhost", "me@me.me", "Testing a mod.", "This email was sent via my main_class but this is a mod that extended main_class without renaming it.");

好的,这不是我的用法,但我相信你明白了,我的课程是一个 CMS 后端,我的模块是将一些子域重定向到其他位置,例如 mail.sitegen.com .au 和 phpmyadmin.sitegen.com.au 被重定向到我的 CMS 之外的 web-gui。我还在为我的 CMS 制作更多模组。

顺便说一句:我的扩展分为两类,模组和插件,模组在由我的 CMS (SiteGen) 提供支持的每个站点上运行,插件对每个站点都有自己的设置,它们不是必需的。换句话说,模组由我选择,插件由网站所有者选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 2012-10-18
    • 2011-10-19
    • 2022-01-13
    相关资源
    最近更新 更多