Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 类的非显式扩展?_Php_Oop_Class_Extension Methods - Fatal编程技术网

Php 类的非显式扩展?

Php 类的非显式扩展?,php,oop,class,extension-methods,Php,Oop,Class,Extension Methods,场景 系统在/system/classes/中声明了类 应用程序具有在/application/classes/中声明的类 如果应用程序文件夹中的类与系统文件夹中的类同名,则应用程序文件夹中的类应扩展系统文件夹中的类 并非系统文件夹中的所有类都将被应用程序文件夹中的类覆盖 问题 如果应用程序文件夹中有类,如何使系统文件夹中的类仅扩展应用程序类中的类 NB:所有可以覆盖的类都是静态类 NB:即使我们必须将应用程序类命名为my\u className,只要我们仍然可以调用className::fun

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

如果应用程序文件夹中的类与系统文件夹中的类同名,则应用程序文件夹中的类应扩展系统文件夹中的类

并非系统文件夹中的所有类都将被应用程序文件夹中的类覆盖

问题
如果应用程序文件夹中有类,如何使系统文件夹中的类仅扩展应用程序类中的类

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

我想我正在寻找类似于CodeIgniter的方法


编辑

示例类
下面的类用作加载程序,用于加载所有其他类(无论是库、进程还是其他类)。它还用于加载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;
    }

}
类负载{
受保护的家庭佣工;
受保护的静态$configs;
受保护的静态库;
受保护的静态进程;
受保护的静态$js;
受保护的静态$css;
公共静态函数init(){
self::$helpers=new stdClass();
self::$libraries=newstdclass();
self::$configs=new stdClass();
self::$processs=newstdclass();
self::$css=newstdclass();
self::$js=new stdClass();
}
公共静态函数配置($name){
if(isset(self:$configs->$name)和&is_对象(self:$configs->$name))
返回self::$configs->$name;
if(是_文件(CONFIG_DIR.$name.'.php')){
需要一次(CONFIG_DIR.$name.'.php');
self::$configs->$name=new$name();
返回self::$configs->$name;
}
引发新异常('无法加载配置文件\'.$name.'\'');
返回false;
}
公共静态函数助手($name){
if(isset(self::$helpers->$name)和&is_对象(self::$helpers->$name))
返回自我::$helpers->$name;
if(是_文件(APP_HELPER_DIR.$name.'.php')){
需要一次(APP_HELPER_DIR.$name.'.php');
self::$helpers->$name=new$name();
返回自我::$helpers->$name;
}
if(是_文件(HELPER_DIR.$name.'.php')){
require_once(HELPER_DIR.$name.'.php');
self::$helpers->$name=new$name();
返回自我::$helpers->$name;
}
引发新异常('无法加载帮助程序文件\'.$name.'\'');
返回false;
}
公共静态函数库($name,$params=array()){
if(空($params)&&isset(self::$libraries->$name)&&is_对象(self::$libraries->$name))
返回self::$libraries->$name;
if(是_文件(APP_LIBRARY_DIR.$name.'.php')){
需要一次(APP_LIBRARY_DIR.$name.'.php');
self::$libraries->$name=新$name($params);
返回self::$libraries->$name;
}
if(是_文件(LIBRARY_DIR.$name.'.php')){
需要一次(库目录$name.'.php');
self::$libraries->$name=new$name();
返回self::$libraries->$name;
}
引发新异常('无法加载库文件\'.$name.'\'');
返回false;
}
公共静态函数进程($name,$args=array()){
if(isset(self::$processs->$name)&&is_对象(self::$processs->$name))
返回self::$processs->$name;
if(是_文件(PROCESS_DIR.$name.'.php')){
需要一次(PROCESS_DIR.$name.'.php');
if(空($args)){
self::$processs->$name=new$name();
返回self::$processs->$name;
}否则{
self::$processs->$name=新的ReflectionClass($name);
返回self::$processs->$name->newInstanceArgs($args);
}
}
引发新异常('无法加载进程文件\'.$name.'\'');
返回false;
}
公共静态函数css($name){
if(isset(self::$css->$name)&&&!empty(self::$css->$name))
返回self::$css->$name;
self::$css->$name='';
返回self::$css->$name;
}
公共静态函数js($name){
if(isset(self::$js->$name))
返回self::$js->$name;
self::$js->$name='';
返回self::$js->$name;
}
公共静态函数模板($name,$vars=array()){
if(是_文件(模板_DIR.$name.'.php')){
ob_start();
如果(!空($vars))
摘录(VAR);
要求(模板_DIR.$name.'.php');
$contents=ob_get_contents();
ob_end_clean();
返回$contents;
}
引发新异常('无法加载模板文件\'.$name.'\'');
返回false;
}
}

据我所知,CodeIgniter确实会替换类,而不是扩展类

更实际的方法是通过友好方式生成代码:

$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通常被认为是邪恶的,原因很好,所以一定要仔细检查您的代码。 您可能需要重新思考您的框架设计


更新:如果类只是静态的,那么您可能需要查看模式和_调用()。这就足够了,可以避免eval()路线。

据我所知,代码点火器确实会取代cl