类的非显式扩展?

发布于 2024-10-19 03:44:54 字数 5192 浏览 3 评论 0原文

场景
系统/system/classes/中声明了类。
应用程序具有在/application/classes/中声明的类。

如果application文件夹中存在与以下同名的类system 文件夹中的类,那么 application 文件夹中的类应该扩展 system 文件夹中的类。

并非system文件夹中的所有类都会被application文件夹中的类覆盖。

问题
如果系统文件夹中存在类,如何才能扩展应用程序文件夹中的类应用程序文件夹。

注意:所有可以被覆盖的类都是静态类
注意:即使我们必须将应用程序类命名为my_className,只要我们仍然可以调用className: :functionName()

我想我正在寻找类似于 Code Igniter 的做法的东西。


Edit

示例类
下面的类用作加载器来加载所有其他类(无论是库、进程还是其他类)。它还用于加载 css/image/js 文件等。

如果用户要扩展该类,他们可能需要添加一个 ini() 函数,该函数将用于加载 ini 文件。

class load {

    protected static $helpers;
    protected static $configs;
    protected static $libraries;
    protected static $processes;
    protected static $js;
    protected static $css;

    public static function init() {
        self::$helpers = new stdClass();
        self::$libraries = new stdClass();
        self::$configs = new stdClass();
        self::$processes = new stdClass();
        self::$css = new stdClass();
        self::$js = new stdClass();
    }

    public static function config($name) {
        if (isset(self::$configs->$name) && is_object(self::$configs->$name))
            return self::$configs->$name;

        if (is_file(CONFIG_DIR . $name . '.php')) {
            require_once(CONFIG_DIR . $name . '.php');
            self::$configs->$name = new $name();
            return self::$configs->$name;
        }
        throw new exception('Could not load config file \'' . $name . '\'');
        return false;
    }

    public static function helper($name) {
        if (isset(self::$helpers->$name) && is_object(self::$helpers->$name))
            return self::$helpers->$name;

        if (is_file(APP_HELPER_DIR . $name . '.php')) {
            require_once(APP_HELPER_DIR . $name . '.php');
            self::$helpers->$name = new $name();
            return self::$helpers->$name;
        }

        if (is_file(HELPER_DIR . $name . '.php')) {
            require_once(HELPER_DIR . $name . '.php');
            self::$helpers->$name = new $name();
            return self::$helpers->$name;
        }
        throw new exception('Could not load helper file \'' . $name . '\'');
        return false;
    }

    public static function library($name, $params = array()) {
        if (empty($params) && isset(self::$libraries->$name) && is_object(self::$libraries->$name))
            return self::$libraries->$name;

        if (is_file(APP_LIBRARY_DIR . $name . '.php')) {
            require_once(APP_LIBRARY_DIR . $name . '.php');
            self::$libraries->$name = new $name($params);
            return self::$libraries->$name;
        }

        if (is_file(LIBRARY_DIR . $name . '.php')) {
            require_once(LIBRARY_DIR . $name . '.php');
            self::$libraries->$name = new $name();
            return self::$libraries->$name;
        }
        throw new exception('Could not load library file \'' . $name . '\'');
        return false;
    }

    public static function process($name, $args = array()) {
        if (isset(self::$processes->$name) && is_object(self::$processes->$name))
            return self::$processes->$name;

        if (is_file(PROCESS_DIR . $name . '.php')) {
            require_once(PROCESS_DIR . $name . '.php');
            if (empty($args)) {
                self::$processes->$name = new $name();
                return self::$processes->$name;
            } else {
                self::$processes->$name = new ReflectionClass($name);
                return self::$processes->$name->newInstanceArgs($args);
            }
        }
        throw new exception('Could not load process file \'' . $name . '\'');
        return false;
    }

    public static function css($name) {
        if (isset(self::$css->$name) && !empty(self::$css->$name))
            return self::$css->$name;

        self::$css->$name = '<link rel="stylesheet" type="text/css" href="' . CSS_PATH . $name . '.css">';
        return self::$css->$name;
    }

    public static function js($name) {
        if (isset(self::$js->$name))
            return self::$js->$name;

        self::$js->$name = '<script src="' . JS_PATH . $name . '.js"></script>';
        return self::$js->$name;
    }

    public static function template($name, $vars = array()) {
        if (is_file(TEMPLATE_DIR . $name . '.php')) {
            ob_start();
            if (!empty($vars))
                extract($vars);
            require(TEMPLATE_DIR . $name . '.php');
            $contents = ob_get_contents();
            ob_end_clean();
            return $contents;
        }
        throw new exception('Could not load template file \'' . $name . '\'');
        return false;
    }

}

Scenario
The system has classes declared in /system/classes/.
The application has classes declared in /application/classes/.

If there is class in the application folder that has the same name as a class in the system folder then the class in the application folder should extend the class in the system folder.

Not all classes in the system folder will be overwritten by a class in the application folder.

Question
How can you cause the class in the system folder to extend the class in the application class only if there is a class in the application folder.

NB: All classes that can be overwritten are static classes
NB: Even if we have to name the application classes my_className it is fine, as long as we can still just call className::functionName()

I guess Im looking for something similar to how Code Igniter does it.


Edit

Example Class
The below class is used as a loader to load in all other classes (be they libraries, processes or other). It is also used to load in css/image/js files ect.

If the user was to extend the class they might want to add an ini() function which would be used to load in ini files.

class load {

    protected static $helpers;
    protected static $configs;
    protected static $libraries;
    protected static $processes;
    protected static $js;
    protected static $css;

    public static function init() {
        self::$helpers = new stdClass();
        self::$libraries = new stdClass();
        self::$configs = new stdClass();
        self::$processes = new stdClass();
        self::$css = new stdClass();
        self::$js = new stdClass();
    }

    public static function config($name) {
        if (isset(self::$configs->$name) && is_object(self::$configs->$name))
            return self::$configs->$name;

        if (is_file(CONFIG_DIR . $name . '.php')) {
            require_once(CONFIG_DIR . $name . '.php');
            self::$configs->$name = new $name();
            return self::$configs->$name;
        }
        throw new exception('Could not load config file \'' . $name . '\'');
        return false;
    }

    public static function helper($name) {
        if (isset(self::$helpers->$name) && is_object(self::$helpers->$name))
            return self::$helpers->$name;

        if (is_file(APP_HELPER_DIR . $name . '.php')) {
            require_once(APP_HELPER_DIR . $name . '.php');
            self::$helpers->$name = new $name();
            return self::$helpers->$name;
        }

        if (is_file(HELPER_DIR . $name . '.php')) {
            require_once(HELPER_DIR . $name . '.php');
            self::$helpers->$name = new $name();
            return self::$helpers->$name;
        }
        throw new exception('Could not load helper file \'' . $name . '\'');
        return false;
    }

    public static function library($name, $params = array()) {
        if (empty($params) && isset(self::$libraries->$name) && is_object(self::$libraries->$name))
            return self::$libraries->$name;

        if (is_file(APP_LIBRARY_DIR . $name . '.php')) {
            require_once(APP_LIBRARY_DIR . $name . '.php');
            self::$libraries->$name = new $name($params);
            return self::$libraries->$name;
        }

        if (is_file(LIBRARY_DIR . $name . '.php')) {
            require_once(LIBRARY_DIR . $name . '.php');
            self::$libraries->$name = new $name();
            return self::$libraries->$name;
        }
        throw new exception('Could not load library file \'' . $name . '\'');
        return false;
    }

    public static function process($name, $args = array()) {
        if (isset(self::$processes->$name) && is_object(self::$processes->$name))
            return self::$processes->$name;

        if (is_file(PROCESS_DIR . $name . '.php')) {
            require_once(PROCESS_DIR . $name . '.php');
            if (empty($args)) {
                self::$processes->$name = new $name();
                return self::$processes->$name;
            } else {
                self::$processes->$name = new ReflectionClass($name);
                return self::$processes->$name->newInstanceArgs($args);
            }
        }
        throw new exception('Could not load process file \'' . $name . '\'');
        return false;
    }

    public static function css($name) {
        if (isset(self::$css->$name) && !empty(self::$css->$name))
            return self::$css->$name;

        self::$css->$name = '<link rel="stylesheet" type="text/css" href="' . CSS_PATH . $name . '.css">';
        return self::$css->$name;
    }

    public static function js($name) {
        if (isset(self::$js->$name))
            return self::$js->$name;

        self::$js->$name = '<script src="' . JS_PATH . $name . '.js"></script>';
        return self::$js->$name;
    }

    public static function template($name, $vars = array()) {
        if (is_file(TEMPLATE_DIR . $name . '.php')) {
            ob_start();
            if (!empty($vars))
                extract($vars);
            require(TEMPLATE_DIR . $name . '.php');
            $contents = ob_get_contents();
            ob_end_clean();
            return $contents;
        }
        throw new exception('Could not load template file \'' . $name . '\'');
        return false;
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

音盲 2024-10-26 03:44:54

据我所知,代码 Igniter 确实替换了类,而不是扩展它们。

更实用的方法是动态生成代码:

$code = file_get_contents($appFile);
if ( file_exists( $systemFile ) )
{
    //don't do this ! Just a proof of concept, use regexp or code tokenizer
    //you will also need to programmatically determine MyClass and SystemClass
    $code = str_replace ('class myClass', 'class MyClass extends SystemClass', $code);
}
eval ($code)

请注意,出于充分的理由,eval 通常被认为是邪恶的,因此请务必仔细检查您的代码。
您可能想重新考虑您的框架设计。

更新:如果类只是静态的,您可能需要查看装饰器 模式和 __call() __get() __set()。这可能就足够了,并且可以避免 eval() 路线。

As far as I know code Igniter do replace classes, rather than extending them.

The more pratical way is to dinamically generate the code:

$code = file_get_contents($appFile);
if ( file_exists( $systemFile ) )
{
    //don't do this ! Just a proof of concept, use regexp or code tokenizer
    //you will also need to programmatically determine MyClass and SystemClass
    $code = str_replace ('class myClass', 'class MyClass extends SystemClass', $code);
}
eval ($code)

Please note that eval is generally considered evil for good reasons, so be sure to double check your code.
You may want to re-think your framework design instead.

UPDATE: if classes are just statical you may want to look into the Decorator pattern and __call() __get() __set(). That may suffice and avoid the eval() route.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文