如何使用更多类扩展php类

时间:2011-01-19 05:45:09

标签: php class join merge

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

class main_class extends main_class {...}

但是php并不开心。 :(

那么我虽然对自己问一下stackoverflow,但我相信有人会知道一个解决方案。 从来没有经过几个小时的调试,我只用一点代码自我解决了我的问题。

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

所以这是我的解码:

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函数。

感谢任何发布答案的人。

2 个答案:

答案 0 :(得分:0)

在C#中,您可以通过定义partial class来完成此操作。它基本上就像在不同的文件中编写更多相同的类。我不确定PHP是否支持此功能,但本文可能会有所帮助吗?

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

答案 1 :(得分:0)

自我解决:) 我已经自己想出来了,我相信其他人会发现它很有用所以这里是我的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后端,我的mod是将一些子域重定向到其他位置,例如mail.sitegen.com .au和phpmyadmin.sitegen.com.au被重定向到我的CMS的web-gui外面。我也为我的CMS制作了更多的mod。

BTW:我的扩展分为两类,mods和插件,mods在我的CMS(SiteGen)支持的每个站点上运行,插件有自己的设置,每个站点都不需要。换句话说,mod由我选择,插件由网站所有者选择。