方案
系统具有在/system/classes/
中声明的类
应用程序具有在/application/classes/
中声明的类。
如果 application 文件夹中的类与 system 文件夹中的类同名,则应用程序中的类文件夹应该扩展 system 文件夹中的类。
system 文件夹中的所有类都不会被 application 文件夹中的类覆盖。
问题
如果中有一个类,如何使 system 文件夹中的类扩展应用程序类 中的类?应用程序文件夹。
NB:所有可以覆盖的类都是静态类
NB:即使我们必须将应用程序类命名为 my_className ,也可以,只要我们仍然可以调用className::functionName()
我想我正在寻找类似Code Igniter的方法。
<小时/> 的修改
示例类
下面的类用作加载器以加载所有其他类(无论是库,进程还是其他类)。它还用于加载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;
}
}
答案 0 :(得分:1)
据我所知,代码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通常被认为是邪恶的,因此请务必仔细检查您的代码。 您可能希望重新考虑您的框架设计。
更新:如果类只是静态的,您可能需要查看 Decorator 模式和__call()__ get()__ set()。这可能足以避免eval()路由。